java面向对象----抽象类 接口

news2025/1/8 12:08:39

目录

抽象类与抽象方法

概念

抽象类应用 

接 口

概念

接口的特点:

接口应用举例

Java 8中关于接口的改进

 内部类

如何声明局部内部类

局部内部类的特点

匿名内部类

总结


抽象类与抽象方法

概念

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一 般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类

abstract关键字来修饰一个类,这个类叫做抽象类

        抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。

abstract来修饰一个方法,该方法叫做抽象方法

        抽象方法:只有方法的声明,没有方法的实现。以分号结束:public abstract void talk();

        含有抽象方法的类必须被声明为抽象类。​​​​​

  • 不能用abstract修饰变量、代码块、构造器;
  • 不能用abstract修饰私有方法、静态方法、final的方法、final的类。
abstract class A {
    abstract void m1();
    public void m2() {
        System.out.println("A类中定义的m2方法");
    }
}
class B extends A {
    void m1() {
        System.out.println("B类中定义的m1方法");
    }
}
public class Test {
    public static void main(String args[]) {
    A a = new B();
    a.m1();
    a.m2();
    }
}

抽象类应用 

抽象类是用来模型化那些父类无法确定全部实现,而是由其子类提 供具体实现的对象的类。
在航运公司系统中, Vehicle 类需要定义两个方法分别计算运输工具的燃料效率和行驶距离。
卡车 (Truck) 和驳船 (RiverBarge) 的燃料效率和行驶距离的计算方法完全不同。Vehicle 类不能提供计算方法,但子类可以。

解决方案
Java 允许类设计者指定:超类声明一个方法但不提供实现,该方法的实现由子类提供。 这样的方法称为 抽象方法 。有一个或更多抽象方法的类称为 抽象类
Vehicle 是一个抽象类,有两个抽象方法
public abstract class Vehicle{
    public abstract double calcFuelEfficiency(); //计算燃料效率的抽象方法
    public abstract double calcTripDistance(); //计算行驶距离的抽象方法
}
public class Truck extends Vehicle{
    public double calcFuelEfficiency( ) { //写出计算卡车的燃料效率的具体方法 }
    public double calcTripDistance( ) { //写出计算卡车行驶距离的具体方法 }
}
public class RiverBarge extends Vehicle{
    public double calcFuelEfficiency( ) { //写出计算驳船的燃料效率的具体方法 }
    public double calcTripDistance( ) { //写出计算驳船行驶距离的具体方法}
}
抽象类不能实例化 new Vihicle()是非法的

接 口

概念

一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。

另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又 没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打 印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都 支持USB连接。

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/...则必须能...”的思想。

继承是一个"是不是"的关系,而接口实现则是 "能不能" 的关系。 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。

接口(interface)抽象方法常量值定义的集合。

接口的特点:

  • interface来定义。
  • 接口中的所有成员变量都默认是由public static final修饰的。
  • 接口中的所有抽象方法都默认是由public abstract修饰的。
  • 接口中没有构造器。
  • 接口采用多继承机制。
public interface Runner {
public static final int ID = 1;
public abstract void start();
public abstract void run();
public abstract void stop();
}

定义Java类的语法格式:先写extends,后写implements

class SubClass extends SuperClass implements InterfaceA{ }

一个类可以实现多个接口,接口也可以继承其它接口。

实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。

接口的主要用途就是被实现类实现。(面向接口编程)

与继承关系类似,接口与实现类之间存在多态性

接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义 (JDK7.0及之前),而没有变量和方法的实现。

接口应用举例

interface Runner {
    public void start();
    public void run();
    public void stop();
}
class Person implements Runner {
    public void start() {
        // 准备工作:弯腰、蹬腿、咬牙、瞪眼
        // 开跑
    }
    public void run() {
        // 摆动手臂
        // 维持直线方向
    }
    public void stop() {
        // 减速直至停止、喝水。
    }
}

Java 8中关于接口的改进

Java 8中,你可以为接口添加静态方法默认方法。从技术角度来说,这是完 全合法的,只是它看起来违反了接口作为一个抽象定义的理念。

静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行 其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。

默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。 我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。 比如:java 8 API中对CollectionListComparator等接口提供了丰富的默认方法。

public interface AA {
    double PI = 3.14;
    public default void method() 
    System.out.println("北京");
    }
    default String method1() {
    return "上海";
    }
    public static void method2() {
    System.out.println(“hello lambda!");
    }
}

若一个接口中定义了一个默认方法,而另外一个接口中也定义了一个同名同 参数的方法(不管此方法是否是默认方法),在实现类同时实现了这两个接口时,会出现:接口冲突。

解决办法:实现类必须覆盖接口中同名同参数的方法,来解决冲突。

若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非抽象方法,则不会出现冲突问题。

因为此时遵守:类优先原则。接口中具有相同名称和参数的默认方法会被忽略。

 内部类

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使 用内部类。

  • Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类
  • Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
  • Inner class的名字不能与包含它的外部类类名相同;
  •  成员内部类static成员内部类和非static成员内部类) 局部内部类(不谈修饰符)、匿名内部类
class Outer {
    private int s;
    public class Inner {
    public void mb() {
        s = 100;
        System.out.println("在内部类Inner中s=" + s);
    }
}
public void ma() {
    Inner i = new Inner();
    i.mb();
    }
}
public class InnerTest {
    public static void main(String args[]) {
        Outer o = new Outer();
        o.ma();
    }
}

如何声明局部内部类

只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类

但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型

局部内部类的特点

内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号。

  • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方 都不能使用该类。
  • 局部内部类可以使用外部类的成员,包括私有的。
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
  • 局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
  • 局部内部类不能使用static修饰,因此也不能包含静态成员

匿名内部类

匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一 个实例。一个匿名内部类一定是在new 的后面,用其隐含实现一个接口或实现一个类。
new 父类构造器(实参列表) | 实现接口 (){
// 匿名内部类的类体部分
}
  • 匿名内部类必须继承父类或实现接口
  • 匿名内部类只能有一个对象
  • 匿名内部类对象只能使用多态形式引用 

总结

package com.jyc.p2;
/*
* 一 abstract(抽象的) 关键字
*      abstract 可以用来修饰的结构 类 方法
*
*   Person1 修饰类 抽象类
*       此类不能实例化
*       抽象类中一定有构造器,便于子类实例化调用
*       开发中都会提供抽象类的子类 让子类实例化,完成相关操作
*
*   Person1 修饰方法 抽象方法
*        抽象方法只有方法的声明,没有方法体
*        包含抽象方法的类,一定是一个抽象类,反之抽象类中可以没有抽象方法
*        若子类重写了父类中所有的抽象方法后,此子类可以实例化,
*           若子类没有重写父类中所有的抽象方法则此子类也是一个抽象类 需要使用abstract修饰
*
*   abstract 使用上的注意点
*       abstract不能用来修饰 属性 构造器等结构
*       abstract 不能用来修饰私有方法(private) 静态方法 (static) final的方法 final的类
*
* 二 接口的使用 interface
*       ① 接口使用 interface来定义
*       ② java中接口和类是两个并列的机构
*       ③ 如何定义接口 定义接口中的成员
*           1. jdk7及以前 只能定义全局常量和抽象方法
*                   全局常量     public  static  final的 可以省略
*                   抽象方法     public  abstract  void  walk();可以省略
 *           2. jdk8 增加了静态方法 默认方法
 *                  ① 接口中定义的静态方法只能通过接口来调用
 *                  ② 通过实现类的对象;可以调用接口中的默认方法
 *                  ③ 如果实现类重写了接口中的默认方法,调用时仍然调用的是重写的方法
 *                  ④如果子类(或实现类)继承的父类和实现接口声明了同名同参数的方法,那么子类在没有重写此方法的情况下
 *                     默认调用父类中的同名同参数方法(类优先原则)
 *                  ⑤ 如果实现类实现了多个接口,而这多个接口中定义了同名同参数的方法,那么在实现类没有重写此
 *                      方法的情况下,报错------接口冲突(必选在接口类中重写此方法)
 *
 *      ④ 接口中不能定义构造器,不可以实例化
 *      ⑤ java开发中接口让类去实现(implements)的方式使用
 *      如果类覆盖了接口中所有的抽象方法,则此类就可以实例化
 *      如果类没有覆盖接口中所有的抽象方法,则此实现类扔为一个抽象类
 *      ⑥ java类可以实现多个接口,弥补了java单继承性的局限性
 *          格式:class  AA extends BB implements CC,DD
 *      ⑦ 接口与接口之间可以继承,并且可以多继承
 *      ⑧ 接口的具体使用体现多态性
 *      ⑨ 接口实际上可以看做一种规范
 *
 *
 * 三 内部类
 *  java中允许一个类a声明在一个类b中,则类a是内部类,类b称为外部类
 *  内部类的分类 成员内部类 vs局部内部类(方法内,代码块内 构造器内)
 *      成员内部类
 *         一方面作为外部类的成员,
 *              调用外部类的结构
 *              可以用static 修饰
 *              可以被四种不同权限修饰
 *
 *          另一方面作为一个类
 *            类内可以定义属性 方法 构造器
 *            可以被final 修饰,表示类不能被继承,不使用可以继承
 *            可以被 abstract修饰 不能被实例化
 *
 *关注一下三个问题
 *      如何实例化成员内部类
 *      如何在成员内部类中区分调用外部类的结构
 *      开发中局部内部类的使用
 *
*
*
*
 * */
public class abstracTest {
    public static void main(String[] args) {
         // Person1 p1=new Person1(); 不可以实例化
        // 创建一个匿名子类对象
            Person1 p1=new Person1() {
                public void walk() {
                    System.out.println("匿名子类对象 重写walk");
                }
            };
        abstracTest.methods(p1);
        System.out.println("-----接口-------");
        Plane p2=new Plane();
        p2.fly();//接口的使用
        CompareA.methods(); //接口静方法只能通过接口调用
        subClass s1=new subClass();
        s1.methods1();//执行实现类重写的方法
        s1.methods();  //父类优先
        System.out.println("---------调用-------");
        s1.Mymethods();
        System.out.println("---------内部类-------");
        //静态成员内部类
        InnerClassTest.Cat cat=new InnerClassTest.Cat();
        cat.show();
        InnerClassTest c5=new InnerClassTest();
        InnerClassTest.Dog dog= c5.new Dog();
        dog.show();

    }
    public  static void methods(Person1 p){
        p.walk();
    }



}
abstract class Person1{
    String name;
    int age;
    public Person1(){}
    public Person1(String name, int age){
        this.name=name;
        this.age=age;
    }
    public  abstract  void  walk();
    public  void  eat(){
        System.out.println("人吃饭");
    }
}
class  Student1 extends Person{
    public Student1(String name, int age){
        super(name, age);
    }
    public void  walk(){
        System.out.println("跑");
    };
}
interface  Flyble{
 public  static  final  int Maxs=7990;
 int mians=1;
 public  abstract  void fly();
 void Stop();
}
interface  Attackable{
    void attack();
}
class Plane implements Flyble{
    @Override
    public void fly() {
        System.out.println("飞机飞");
    }

    @Override
    public void Stop() {
        System.out.println("飞机停止");
    }
}
class  Bullet extends Object implements Flyble,Attackable{
    public void fly() {

    }

    @Override
    public void Stop() {

    }
    public  void  attack(){

    }
}
  interface CompareA{
    //静态方法
      public static void methods(){
          System.out.println("北京");
      };
      //默认方法
      public  default void methods1(){
          System.out.println("上海");
      }
      public  default void methods3(){
          System.out.println("杭州");
      }
}
interface CompareB{

    //默认方法
    public  default void methods3(){
        System.out.println("上海");
    }
}
class  superClass{
    public  void methods(){
        System.out.println("父类方法,北京");
    };
}
class  subClass extends superClass implements  CompareA,CompareB{
    public   void methods1(){
        System.out.println("subClass 重写默认方法");
    }
    public   void methods3(){
        System.out.println("类冲突实现类必选重写 杭州");
    }
    //如何在子类(或实现类)的方法中调用父类 ,接口中被重写的方法
    public  void Mymethods(){
        methods1();//调用自己重写的
        super.methods();//调用父类重写的
        CompareA.super.methods1();//调用接口中默认方法
    }
}
class InnerClassTest{
    //成员内部类
    public  void eat(){
        System.out.println("吃");
    }
    class Dog{
        public  void show(){
            System.out.println("狗");
            InnerClassTest.this.eat();
        }
    };
    static class Cat{
        public  void show(){
            System.out.println("猫");
        }
    };

    public  void methods(){
        //内部类
        class AA{}
    }
    {
        //内部类
        class BB{}
    }
 public InnerClassTest(){
     //内部类
    class CC{}
 }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/75557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习之多元线性回归

1、多元线性回归模型:定义:具有多个特征的线性回归模型 多元线性回归模型,见下图: 多元线性回归总结(参数、模型、损失函数、梯度下降算法)见下图:【注意:梯度下降算法每次都是同时…

Vue2中过滤器的用法详解

目录 一、过滤器的概念 二、过滤器的使用位置 三、过滤器的分类 1、全局过滤器 2、本地过滤器 四、过滤器应用实例 1、使用过滤器实现省略号 2、使用过滤器处理时间戳 五、Vue3中已废弃过滤器 过滤器是vue中的一个特性,作用是用于对文本进行格式化的作用。…

动态与静态获取元素

🌵知识点简介 静态获取(querySelectorAll)时,选出的所有元素的数组,不会随着文档操作而改变; 动态获取(getElementById)时,选出的所有元素的数组,会随着文档的…

Paddle 点灯人 之 Tensor

Paddle 点灯人 之 Tensor 文章目录Paddle 点灯人 之 TensorPaddle点灯人介绍Tensor介绍Pytorch和Paddle的相似之处创建张量Tensor图片/文本转TensorDataLoader不需要加ToTensorPaddle中的 Tensor 的属性形状 shape数据类型(dtype)Tensor 的设备位置&…

高压放大器驱动压电器件工作原理

高压放大器在实际应用中经常会进行电容性负载驱动,对压电器件进行驱动,那么工作原理是什么呢,下面就请安泰电子来为我们讲解一下。 高压放大器是提高信号电压的装置,当负载是谐振电路或者耦合电路的时候,要求特定频率范…

Mybatis源码解析(十):一级缓存和二级缓存

Mybatis源码系列文章 手写源码(了解源码整体流程及重要组件) Mybatis源码解析(一):环境搭建 Mybatis源码解析(二):全局配置文件的解析 Mybatis源码解析(三):映射配置文件的解析 Mybatis源码解析(四):s…

转行学python?到底值不值

大学毕业后相当迷茫,不知道做些什么,于是跟着潮流去学了python,当年2w多买的python教程,三个月的时间成功上岸,现在用不着了,文末有领取方式。 面对当前情况,让众多职场人开始紧张,…

《棒球大联盟2nd》:青春赛场·棒球1号位

茂野大吾是个有着现役职业棒球选手的父亲的小学生。他因为向往曾经在棒球大联盟活跃的父亲吾郎,而开始了在少年棒球队“三船海豚队”的棒球训练。但是,因为背负着茂野二世这个称号的压力,无法发挥出原来的水平,以至于1年还不到就放…

基于java+springmvc+mybatis+jsp+mysql的整体衣柜定制系统

项目介绍 管理员后台: 功能:个人中心、客户管理、导购管理、店长管理、厂家管理 客户后台: 功能:个人中心、款式信息管理、款式预订管理、材料信息管理、材料预订管理、定制订单管理、安装信息管理、订单评价管理、联系客户管理 …

我发现了一个React、Vue等所有前端框架都存在的隐秘Bug?

什么 Bug? 昨天有个朋友请教了我一个问题,她在使用原生的 Details 元素封装一个手风琴组件。但是无论如何都不能按照预期工作。 起初我认为是她水平比较差,代码写的有问题。但是她一再向我保证绝对不是她的问题。所以我就抽出时间帮她看了一…

DP2515国产带SPI接口CAN总线控制器芯片兼容替代MCP2515/MCP2515-I/ST

目录什么是CAN?DP2515简介芯片特性参考原理图什么是CAN? CAN是控制器局域网络(Controller Area Network, CAN)的简称,是如今是国际上应用最广泛的现场总线之一,是ISO国际标准化的串行通信协议。在汽车产业中,出于对安…

项目管理必备,教你如何制作甘特图

甘特图是项目管理中常用的工具,又被称为横道图。 由表格和条形图组成,左侧显示项目中所有的任务及时间,右侧一条状进度条显示项目每个任务的进度。 因为它极其好用,不仅在比较大型和复杂的项目中被广泛使用,在日常工…

iPhone 微信多开,如何在苹果手机上安装多个微信,爱思助手怎么用?IPA文件怎么弄?

苹果实现微信多开,用爱思助手就能实现,简单易上手。爱思助手怎么用?IPA文件怎么弄? 设备:Mac(11.6)/14pm 助手:爱思助手 需求:在最新的苹果手机上实现微信多开 博主上个月底抢的14pm终于到手了,之前多开微信一直用的大灰免费版的,怎么说呢?挺好用的但是不稳定,…

简单的有限状态机(FSM)的示例一

一个简单的有限状态机, 三种状态: 停止状态运行状态暂停状态 三个事件 StartPauseStop 状态转换说明: Stopped状态:通过Start事件转换为Running状态Running状态:通过Pause事件可转换为Pause状态Pause状态&#…

什么是零知识证明(ZK Proof)?Web2.0通往Web3.0的入口技术

古老的难题 女:你爱我吗? 男:爱! 女:怎么证明? 男:…… 零知识证明的定义 零知识证明(Zero-Knowledge Proof)也叫做最小泄露证明,能充分证明自己是某种权益的合法拥有者&#xff0c…

【Docker】第四章 容器管理

4.1 创建容器常用选项 指令 描述 -i, --interactive 交互式 -t, --tty 分配一个伪终端 -d, --detach 运行容器到后台 -a, --attach list 附加到运行的容器 --dns list 设置DNS服务器 -e, --env list 设置环境变量 --env-file list 从文件读取环境变量 -p, --p…

知识点14--搭建k8s本地测试集群

首先要做安装前的准备: 1、最少三台节点,CentOS 7系统,每台不低于4核4G资源,并配置host域名 [roothdp1 ~] cat /etc/hosts 192.168.88.186 hdp1 192.168.88.187 hdp2 192.168.88.188 hdp32、所有节点保证时间同步、并做SSH互信 …

离散数学与组合数学-数理逻辑-01命题与联结词

文章目录1. 命题与联结词1.1 命题1.2 常用联结词1.3 命题公式1.4 命题的等值演算与推理等价关系式基本等价式1. 命题与联结词 1.1 命题 命题:我们对确定对象做出的陈述句称为命题(propositions and statements 命题或陈述)。当判断为真时&a…

《小猫猫大课堂》2—开启C语言的世界,喵!

更新不易,麻烦多多点赞,欢迎你的提问,感谢你的转发, 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我…

学不会的python之正则表达式详解(re模块)

本篇博客介绍了正则表达式与在python中的应用(re模块),及一些在开发中常见的模式示例。参考书籍《python核心编程(第三版)》 学不会的python之正则表达式正则表达式(模式)简介正则应用搜索与匹配注意特殊符号与字符择一匹配匹配单个字符注意问题起始、结尾、单词边界…