Java-抽象类和接口

知识点1-抽象的概念与定义

  • 抽象类的概念: 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

  • 抽象类必须用abstract关键字来修饰。

  • 抽象方法的概念: 没有功能主体的方法称为抽象方法

  • 抽象方法必须用abstract关键字来修饰,只有方法声明,没有方法体,且必须定义在抽象类中。

知识点2-抽象类的特点

  • 抽象类不可以被实例化,也就是不可以用new创建对象 ,但有构造方法

  • 抽象类通过其子类实例化,而子类需要覆盖(重写)掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。

  • 方法只有声明没有实现时,该方法就是抽象方法,需要用abstract来修饰,抽象方法必须定义在抽象类中,该类也必须被abstract来修饰。

  • 用abstract修饰的类就是抽象类。抽象方法必须定义在抽象类中。但是抽象类中不一定有抽象方法。

  • 抽象类可以有成员属性和非抽象的成员方法。

  • 抽象类可以没有抽象方法。

  • 抽象类可以继承普通类与抽象类。

  • 抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化。

  • abstract与其他修饰符的关系:

    • final与abstract不能共存:

    • final:它的作用 修饰类代表不可以继承 修饰方法不可重写

    • abstract修饰类就是用来被继承的,修饰方法就是用来被重写的。

  • static 修饰的方法可以用类名调用,对于abstract修饰的方法没有具体的方法实现,所以不能直接调用,也就是说不可以与static共存。

  • private 修饰的只能在本类中使用,abstract方法是用来被子类进行重写的,有矛盾所有不能共存

知识点3-抽象类与普通类的异同

  • 相同点

    • 抽象类和普通类都是用来描述事物的,都在内部定义了成员。

  • 不同点

    • 普通类有足够信息来描述事物,抽身象类描述事物的信息有可能不够充足

    • 普通类不能定义抽象方法,只能定义普通方法,抽象类中可以定义抽象方法,同时也可以定义普通方法

    • 普通类可以被实例化,抽象类不可以被实例化

知识点4-抽象练习

复制代码
/**
 * 父类(抽象类)
 */
public abstract class MyShape {
    //计算周长
    public abstract double getLen();

    //计算面积
    public abstract double getArea();
}
复制代码
复制代码
/**
 * 子类继承父类(抽象类)
 */
public class Rect extends MyShape {
    //定义成员变量 宽高
    private double width;
    private double height;
    public Rect(double width, double height) {
        this.width = width;
        this.height = height;
    }
    public double getWidth() {
        return width;
    }
    public double getHeight() {
        return height;
    }
    @Override
    public double getLen() {
        return 2 * (this.width + this.height);
    }
    @Override
    public double getArea() {
        return this.width * this.height;
    }
}
复制代码
复制代码
/**
 * 子类 继承 父类MyShape(抽象类)
 */
public class Circle extends MyShape {
    private double r;
    private static final double PI = 3.14; //定义常量PI
    public Circle(double r) {
        this.r = r;
    }
    public double getR() {
        return r;
    }
    @Override
    public double getLen() {
        return 2 * PI * this.r;
    }
    @Override
    public double getArea() {
        return PI + this.r * this.r;
    }
}
复制代码
复制代码
public class MyShapeTest {
    public static void main(String[] args) {
        System.out.println("==矩形的周长和面积==");
        MyShape rect = new Rect(20, 30);
        showInfo(rect);
        System.out.println("==圆形的周长和面积==");
        MyShape circle = new Circle(30);
        showInfo(circle);
    }
    public static void showInfo(MyShape shape) {
        System.out.println("周长为:" + shape.getLen());
        System.out.println("面积为:" + shape.getArea());
    }
}
/**
 * ==矩形的周长和面积==
 * 周长为:100.0
 * 面积为:600.0
 * ==圆形的周长和面积==
 * 周长为:188.4
 * 面积为:903.14
 */
复制代码

知识点5-接口的概念

  • 为什么使用接口?

    接口(interface):在java中接口主要是使用来拓展定义类的功能,可以弥补Java中单继承的缺点。

  • 接口(硬件类接口)

    • 人类与电脑等,或人类与程序之间的接口,称为用户界面

  • 接口(软件类接口)

    • 接口简单理解就是一种约定,接口是设计层面的概念,往往由设计师设计,将定义与实现分离,程序员实现接口,实现具体方法

  • 接口的定义

    • java接口是一系列方法的声明,是一些抽象的集合,一个接口只有抽象方法没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

    • 简单地说,接口就是特殊的抽象类,即所有方法都是抽象方法的抽象类就是Java中的接口(interface)

知识点6-定义接口的格式

  • 定义接口

    接口中的成员修饰符是固定的:

    • public static final 修饰的变量变常量,该值不能改变,只能读。

    • 修饰符:可选,用于指定接口的访问权限,可选值为public。即使省略,也依然是public。

    • 接口名:必选参数,用于指定接口的名称,接口名必须是合法的Java标识符。一般情况下,要求首字母大写。

    • 方法:接口中的方法只有定义而没有被实现。

  • 接口中的成员示例:

    复制代码
    public interface Pencil {
        //下面2行代码是等价
        //public static final double PI = 3.14;
        double PI = 3.14;
    
        //下面2行代码是等价
        //接口的所有方法都是抽象方法,所以abstract就可以省略了
        //接口的方法就是方法的规范为其他实现类服务,所以默认public,其他的访问权限限定符不能使用
        //public abstract void write();
        void write();
    }
    复制代码

知识点7-类与接口的关系

  • 类和接口是实现关系,实现类的声明形式如下:

    • 类与接口之间是实现关系,类实现接口

    • 接口不可以被实例化

    • 实现了接口的实现类必须重写接口中所有抽象方法后,这个子类才可以被实例化,否则报错

    • 一个类可以实现多个接口,多个接口用逗号分隔,也可以不实现接口

    • Java不支持多继承,Java将多继承机制进行改良变成了多实现

    • 一个类在继承另一个类同时,还可以实现多个接口

    • 接口的出现避免了单继承的局限性

  • 类实现接口的示例:

    
    
    public interface Pencil {
        double PI = 3.14;
        void write();
    }
    public interface Eraser {
        /**
         * 删除
         */
        void remove();
    }
    /**
     * 接口可以多继承其他接口
     */
    public interface InterfaceTest extends Pencil, Eraser {
    }
    复制代码
    /**
     * PencilWithEraser类实现Pencil,Eraser两个
     * java的类是单继承(类)多实现(接口)
     */
    public class PencilWithEraser implements Pencil, Eraser {
        //public class PencilWithEraser implements InterfaceTest {
        @Override
        public void remove() {
            System.out.println("删除数据");
        }
        @Override
        public void write() {
            System.out.println("写数据");
        }
    }
    复制代码
    复制代码
    public class PencilWithEraserTest {
        public static void main(String[] args) {
            PencilWithEraser pwe1 = new PencilWithEraser();
            pwe1.write();
            pwe1.remove();
            //类实现多个接口,使用接口类型接收new的对象,会出现 有的接口类型没有对应方法,进行强转对应的接口类型
            // 常用的方法之一
            Pencil pwe2 = new PencilWithEraser();
            pwe2.write();
            //不能调用 因为Pencil接口类型没有remove方法
            //pwe2.remove();
            //强转成 Eraser 接口类型
            Eraser eas = (Eraser) pwe2;
            eas.remove();
        }
    }
    /**
     * 写数据
     * 删除数据
     * 写数据
     * 删除数据
     */
    复制代码

知识点8-接口和接口的关系

  • 接口和接口之间是继承关系

     

    • 接口与接口之间是继承关系,而且可以多继承

    • 接口的出现避免了单继承的局限性

案例

  • 需求说明: 世界上有很多人种,例如中国人、美国人等,他们所说的语言各不相同。不管是什么人种,他们都是人类

  • 实现步骤:

    (1) 创建一个接口Person,定义一个抽象方法say()

    (2) 创建Chinese 类实现Person,重写say方法

    (3) 创建American 类实现Person,重写say方法

public interface Person {
    void say();
}
public class Chinese implements Person {
    @Override
    public void say() {
        System.out.println("讲中文");
    }
}
public class American implements Person {
    @Override
    public void say() {
        System.out.println("讲英语");
    }
}
复制代码
public class PersonTest {
    public static void main(String[] args) {
//        Chinese chinese1 = new Chinese();
//        chinese1.say();
//        American american1 = new American();
//        american1.say();
        //使用接口做为类型,不再使用具体实现类作为类型,但new还是要使用实现类
        //也是多态的表现之一
        Person chinese = new Chinese();
        chinese.say();
        Person american = new American();
        american.say();
    }
}
/**
 *讲中文
 *讲英语
 */
复制代码

知识点9-接口与抽象类的区别

  • 在Java中接口是一个比抽象类更加抽象的概念,由于只声明行为,因此在接口中的方法均是抽象的,下表中罗列了接口和抽象类的差异:

     abstract classinterface
    属性 不用限制 public 静态 final 常量
    构造方法 可有可无 没有
    普通方法 可以有具体方法 必须是public抽象方法
    子类 单一继承 多重实现(接口继承接口时为多重继承)
  • 抽象类体现继承关系,一个类只能单继承

  • 接口体现实现关系,一个类可以多实现

  • 抽象类是继承 is a关系 (所属关系)在定义该体系的基本共性内容

  • 接口是实现是like a关系(不所属关系)在定义该体系额外功能

知识点10-接口可实现多继承原因

  • 接口继承与类继承对比:

    • Java类的继承是单一继承,Java接口的继承是多重继承

  • 接口可实现多继承原因分析:

    • 不允许类多重继承的主要原因是,如果A同时继承B和C,而B和C同时有一个D方法,A无法确定该继承那一个

    • 接口全都是抽象方法,不存在实现冲突,继承谁都可以,所以接口可继承多个接口

知识点11- JDK8接口的默认方法

  • Java8之前,Java接口纯粹是契约的集合,是一种程序设计的表达方式。从数据抽象的角度看,能够在不定义class的同时又可以定义type,是程序设计中强大而有用的机制。Java接口就是这些纯粹的接口组成的数据抽象

  • Java8之前,接口不能升级。因为在接口中添加一个方法,会导致老版本接口的所有实现类的实现新的方法(涉及到的类全部改动)

  • Java8之后,lambda表达式作为核心出现,为了配合lambda表达式,JDK中Collection库需要添加新的方法,如forEach(),stream()等,于是引入了默认方法(defender methods,Virtual extension methods)。

  • 默认方法是库/框架设计者的后悔药。对于以前的遗留代码,大家都不知道有这个新方法,既不会调用,也不会去实现,如同不存在;编写新代码的程序员可以将它视为保底的方法体。类型层次中任何符合override规则的方法,优先于默认方法,因为遗留代码可能正好有同样的方法存在

  • 默认方法的声明很简单,直接在接口中把方法声明为default,之后再写方法的实现即可。这样所有的实现类都会继承这个方法:

     

  • 默认方法理论上抹杀了Java接口与抽象类的本质区别-前者是行为契约的集合,后者是接口与实现的结合体。当然,语法上两者的差别和以前一样。这就需要我们来自觉维护两者的本质区别,把默认方法作为库、框架向前兼容的手段

  • 实例化实现接口的匿名类对象

public interface Apple {
    void print();
}
复制代码
public class AppleTest {
    public static void main(String[] args) {
        AppleTest test = new AppleTest();
        //new 是一个实现Apple接口的匿名类(构造方法),创建了实现Apple接口的匿名类的对象
        Apple a = new Apple() {
            //匿名类的实现接口的方法 由程序员来完成
            @Override
            public void print() {
                System.out.println("我是苹果");
            }
        };
        //print就是存在就是上面写 匿名类对象的print方法
        a.print();
    }
}
复制代码
posted @   carat9588  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示