细谈java抽象类和接口

本文介绍了抽象类和接口在Java中的概念和使用。抽象类是包含抽象方法的类,不能实例化,用于被子类继承并实现其抽象方法。接口则定义了一组规范,是多个类公共行为的标准,类通过实现接口来遵循这些规范。抽象类和接口在设计中起着重要的作用,抽象类关注于抽象事物,而接口关注于行为规范。一个类可以实现多个接口,但只能继承一个抽象类。Java中,接口间的继承允许接口复用和扩展。
摘要由CSDN通过智能技术生成

抽象类和接口

抽象类

抽象类:如果一个类中没有足够的信息来描绘一个对象,那么这个类就是抽象类

抽象类入门

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ecnu0Hm1-1668610029926)(C:\Users\dongguozhen\AppData\Roaming\Typora\typora-user-images\image-20221115082319474.png)]

  • 矩形、三角形、圆形类都是图形类,因此和Shape的关系应该是extends
  • 虽然Shape类中也有draw方法,但是Shape并不是具体的图形,因此内部的画图的方法是没有方法具体实现的
  • Shape类没有办法描述一个具体的图形,那么里面的draw方法也就没有办法来实现,因此就可以将Shape设置为abstract修饰的抽象类,将draw设置为abstract修饰的抽象方法。

注意:

抽象类也是类,内部可以包含普通方法和属性,甚至构造方法

当抽象类里面有抽象方法后,这个抽象方法必须要在子类中重写该抽象方法。

代码实现

解读:

  • Animal是一个动物类,每个Animal都有叫的方法,但是Animal不是一个具体的动物,所以Animal这个类里面的bark()方法就无法具体的实现。
  • Dog是狗类,首先狗是一个动物,与Animal是继承的关系,狗是一个具体的动物,然后狗这个类就可以实现bark方法具体是怎么叫的
  • Cat是猫类,首先猫是一个动物,与Animal是继承的关系,猫是一个具体的动物,然后猫这个类就也可以实现bark方法具体是怎么叫的

抽象类得语法:

一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用 给出具体的实现体。

package ClassANDObject.Abstract.Abstract01;

abstract class Animal {
    //注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void bark();//抽象类可以不写方法的实现
}
class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }

    @Override
    public void bark() {//重写了抽象类
        System.out.println("小狗 "+getName()+" 正在汪汪叫");
    }
}
class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }

    @Override
    public void bark() {//重写了抽象类
        System.out.println("小猫 "+getName()+" 正在咪咪叫");
    }
}
public class test{

    public static void show(Animal animal){//用多态思想去调用
        animal.bark();
    }
    public static void main(String[] args) {
       // Animal animal = new Animal();  抽象类不能直接实例化对象 因为类是一个抽象的类。
        Dog dog = new Dog("大黄");
        Cat cat = new Cat("小花");
        //直接调用
        /*dog.bark();
        cat.bark();*/
        
        Animal[] animal = {dog,cat};//用多态思想去调用
        for (Animal a:animal) {
            a.bark();
        }

        show(dog);
        show(cat);
    }
}

抽象类的使用细节
  • 抽象类可以不写具体的实现,但是方法要用abstract修饰 —>抽象方法

  • 抽象类不能直接实例化对象 因为类是一个抽象的类。

  • Animal animal = new Animal();
    //报错
    java: ClassANDObject.Abstract.Abstract01.Animal是抽象的; 无法实例化
    
  • 抽象方法不能private的 抽象方法必须要用abstract修饰,private不能同时修饰一个方法。

  • 当一个普通类继承了抽象类,必须重写抽象类当中的抽象方法

  • 抽象方法不能被final static修饰,因为子类最终要重写抽象方法来实现具体的事物。

  • 抽象类存在最大的意义就是为了被继承

  • 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰。

  • 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类。

  • 只要包含抽象方法,这个类必须是抽象类

  • 抽象方法是一定要重写的,所以一定要满足方法重的规则

  • 抽象类中不一定包含抽象方法

  • 抽象类中可以有构造方法,用于子类初始化父类的成员变量

  • 抽象类的价值在与设计,是设计者在设计好之后,让子类继承并实现抽像类

抽象类和普通类的区别

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

抽象类当中可以包含非抽象方法和抽象方法,但是普通类只能包含非抽象方法

抽象类总结

抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法

接口

接口的概念

在这里插入图片描述

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。 在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

接口:制定一个标准,是一个行为的规范

接口快速入门
interface IShape{
    void draw();//接口里面指定一个标准 行为的一种规范
    public static void func(){
        System.out.println("这是一个接口里面静态的方法");
    }
}
class Rect implements IShape{  //这个类和接口的关系是要执行接口的标准  使用关键字 implements

    @Override
    public void draw() {//实现了接口里面的方法,执行接口里面的标准
        System.out.println("画矩形");
    }
    public void info(){
        System.out.println("这是Rect里面的特有的方法");
    }
}
class Flower implements IShape{

    @Override
    public void draw() {
        System.out.println("❀!");
    }
    public void info(){
        System.out.println("这是Flower里面的特有的方法");
    }
}
public class test1 {
    public static void show(IShape iShape){  //向上转型 可以把接口看做一个父类
        iShape.draw();
    }
    public static void show1(IShape iShape){  //向下转型,调用特有的方法
        if(iShape instanceof Rect){
           Rect rect = (Rect) iShape;
           rect.info();
        }else if(iShape instanceof Flower){
            ((Flower) iShape).info();
        }
    }
    public static void main(String[] args) {
       /* Rect rect = new Rect();
        Flower flower = new Flower();*/

        IShape iShape = new Rect();//向上转型
        IShape iShape1 = new Flower();//向上转型
        show(iShape);
        show(iShape1);

        //如果要调用Flower里面特有的方法,需要进行向下转型
        show1(iShape);
        show1(iShape1);

        //如果要调用接口里面静态的方法,那么直接通过接口名来调用
        IShape.func();
    }
}

  1. 接口的定义 使用关键字interface
  2. 接口不能实例化
  3. 接口当中的成员默认是public static final 静态常量
  4. 接口里面的方法不能有具体的实现,只能有抽象方法 但是从jdk8开始,可以写一个default修饰的方法,就可以有具体的实现
  5. 接口的抽象方法默认就是public abstract 修饰的
  6. 接口中不存在构造方法
  7. 接口需要被类实现,使用关键字implements 接口里面的方法默认是抽象方法,所有要在实现接口的类中重写接口的抽象方法
  8. 接口当中可以有static修饰的方法

接口本质是对行为的规范和抽象

接口的使用

接口不能直接使用,必须要有一个实现类来实现接口中定义的所有抽象方法

类与类之间的关系是extends,那么类与接口之间的关系是implements

public interface USB {
   //定义了两个规范
   void open();
   void stop();
}
public class Monse implements USB{ //实现了接口的规范

   @Override
   public void open() {
       System.out.println("打开鼠标");
   }

   @Override
   public void stop() {
       System.out.println("关闭鼠标");
   }
   public void click(){
       System.out.println("点击鼠标");
   }
}
public class KeyBoard implements USB{ //实现了接口的规范

   @Override
   public void open() {
       System.out.println("打开键盘");
   }

   @Override
   public void stop() {
       System.out.println("关闭键盘");
   }
   public void click(){
       System.out.println("使用键盘");
   }
}
public class Computer {
   //站在我们这个方法的角度,我们不关心usb到底引用那个对象,只要实现了接口里面的规范就可以了

   //发生了多态
   public void usbdiv(USB usb){ //发生了向上转型
       usb.open();
       if(usb instanceof Monse){ //向下转型    调用特有的方法,即接口没有定义的规范
           Monse monse = (Monse)usb;
           monse.click();
       }else if(usb instanceof KeyBoard){//向下转型
           ((KeyBoard) usb).click();
       }
       usb.stop();
   }
}
public class test {
   public static void main(String[] args) {

       Monse monse = new Monse();
       Computer computer = new Computer();
       KeyBoard keyBoard = new KeyBoard();
       computer.usbdiv(monse);
       computer.usbdiv(keyBoard);
   }
}

抽象类是对一个事物在抽象,接口是对一个行为在抽象,在设定标准

接口的特性

1:接口是一种引用类型,但是不能直接new一个接口的对象

interface USB{
    
}
public class A{
    public static void main(String[] args){
        USB usb = new USB(); //直接报错
    }
}

2:接口中的每一个方法都是public 修饰的抽象方法,即接口中的方法会被隐士的写为public abstract ,如果写其他的组合会报错

3:接口中的方法不能被接口实现,只能由实现接口的类来实现 要想实现必须写default

4:重写接口的方法时,不能写默认的访问修饰权限

5:接口含有变量,但接口中的变量会被隐士的写为public static final 变量

6:接口中不能有静态代码块和构造方法

7:接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class

8:如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类

实现多个接口

在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承,但是一个类可以实现多个接 口。下面通过类来表示一组动物.

public class Animal { //父类
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
public interface Flying { //飞的接口
    void fly();
}
public interface RUNing {//跑的接口
     void run();
}
public interface Swim { //游泳的接口
    void swimming();
}
public class Dog extends Animal implements RUNing { //子类,并实现了RUNing这个接口的规范
    public Dog(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(getName()+"正在用狗腿跑");
    }
}
public class Duck extends Animal implements RUNing,Swim, Flying {
    //鸭子这个动物具备多种行为  实现了多个接口的规范
    //既要实现多个接口
    //这个类继承了一个父类,同时实现了多个接口
    //鸭子也是一种动物, 既能跑, 也能游, 还能飞

    public Duck(String name) {
        super(name);
    }

    @Override
    public void fly() {
        System.out.println("鸭子"+getName()+"正在飞");
    }

    @Override
    public void run() {
        System.out.println("鸭子"+getName()+"正在跑");
    }

    @Override
    public void swimming() {
        System.out.println("鸭子"+getName()+"正在游泳");
    }
}
public class Fish extends Animal implements Swim{  //子类,并实现了Swim这个接口的规范
    public Fish(String name) {
        super(name);
    }

    @Override
    public void swimming() {
        System.out.println(getName()+"正在游泳");
    }
}
public class Frog extends Animal implements Swim, RUNing { //同时实现多个接口的规范
    //青蛙这个动物具备多种行为
    //既要实现多个接口
    //这个类继承了一个父类,同时实现了多个接口
    //青蛙是一个动物,能游泳还能跑
    public Frog(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println("青蛙"+getName()+"正在跑");
    }

    @Override
    public void swimming() {
        System.out.println("青蛙"+getName()+"正在游泳");
    }
}
public class MAIN {

    //在我们这个角度,我们不关心他到底是那种动物,只能是实现了相应的接口,就行
    //可以不关心具体的类型,只需要关心具体的能力、行为
    public static void run(RUNing runing) {
        runing.run();
    }
    public static void Flying(Flying flying) {
        flying.fly();
    }
    public static void swim(Swim swim) {
        swim.swimming();
    }
    
    public static void main(String[] args) {
        Dog dog = new Dog("旺财");
        run(dog);
        Duck duck = new Duck("唐老鸭");
        Flying(duck);
        run(duck);
        swim(duck);
        Fish fish = new Fish("7秒");
        swim(fish);
        Frog frog = new Frog("呱呱");
        run(frog);
        swim(frog);
    }
}

注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。

接口之间的继承

在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到 多继承的目的。 接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.

interface a{
    void funa();
}
interface b{
    void funb();
}
interface c extends a,b{   //可以看做接口的扩展
    void func();
}
class test implements c{   //这个类必须要实现继承来的所有标准,即方法。

    @Override
    public void funa() {
        
    }

    @Override
    public void funb() {

    }

    @Override
    public void func() {

    }
}

注意:

接口间的继承相当于把多个接口合并在一起.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值