一、抽象类

没有方法主体的方法称为抽象方法,包含抽象方法的类就是抽象类。

Java中使用 abstract 关键字修饰方法和类,抽象方法只有一个方法名,没有方法体。

public  abstract class TestAbstract { //抽象类
    public abstract void run();//抽象方法
}
  1. 如果一个类继承了抽象类,那么该类必须重写父类的所有抽象方法,否则该类也必须声明抽象类。
  2. 抽象类不能创建对象,只能由其子类创建。
  3. 抽象类可以拥有构造方法,是用来给子类创建对象时,初始化父类成员使用的。
  4. 必须有一个子类来实现抽象父类的抽象方法,否则,抽象类的存在无任何意义。
  5. 抽象类不一定拥有抽象方法,但包含抽象方法的类必定是抽象类
public  abstract class Animal { //抽象类
    public abstract void eat();//抽象方法
}
public class Test{
    public static void main(String[] args){
        Dog d = new Dog();
        d.eat();
    }
}
class Dog extends Animal{   //继承动物类并重写eat方法
    public void eat(){
        System.out.println("小狗吃饭了");
    }
}

方法重写,其实是子类对父类抽象方法的完成实现,所以也叫做抽象父类的实现方法。

二、接口

概念: 接口,是Java语言中一种引用数据类型,是方法的集合。

注意:接口虽然和定义类的方式相似,但是一定要明确接口不是类,是一种引用数据类型。

使用:接口不能创建对象,但是可以被实现,使用 interface 关键字定义接口,使用 implements 关键字创建一个实现接口的类(类似于抽象类的实现),然后创建该类对象,就可以调用方法了。

特点:

  1. 接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用 public static final (下篇介绍)修饰。
  2. 接口没有构造方法,不可以创建对象。
  3. 接口中没有静态代码块(static{},加载类时创建,只加载一次)。

内部主要封装了方法:

  1. 抽象方法:使用 abstract 关键词修饰,可以省略,没有方法体。该方法供子类重写实现使用。
  2. 默认方法:使用 default 修饰,不可省略,供子类调用或子类重写。
  3. 静态方法:使用 static 修饰,供接口直接使用。
  4. 私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。
public interface LiveAble { //接口
    //抽象方法(必须重写)
    public  abstract void eat();
    //默认方法(可以被重写,也可以继承默认方法)
    public  default  void  play(){
      System.out.println("玩游戏");
    };
    //静态方法(只能用接口名调用,不可以被实现类的对象调用)
    public static void  run(){
        System.out.println("跑步");
    }
    //私有方法 (辅助默认方法和静态方法)
    private void sing(){
        System.out.println("唱歌");
    }
}
public class Animal implements LiveAble{//实现类
    //重写抽象方法(必须)
    @Override
    public  void  eat(){
        System.out.println("吃大餐");
    };
    //重写默认方法(非必须,默认继承接口方法)
    @Override
    public void play(){
        System.out.println("玩电脑");
    }
}

@Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处:

  • 可以当注释用,方便阅读
  • 编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。例如,你如果没写@Override,而你下面的方法名又写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法。

接口的多实现:一个类可以继承一个父类,同时实现多个接口。

  • 如果接口中的方法和父类方法重名,实现类的对象在调用该方法时会优先调用。
  • 如果多个接口的默认方法存在重复,那么必须对该默认方法进行重写。
//接口
interface A {
    public abstract void showA();
    public default void  show(){
      System.out.println("我是接口A的show方法");
    };
}
interface B {
    public abstract void showA();
    public abstract void showB();
    public default void  show(){
        System.out.println("我是接口B的show方法");
    };
}
//父类
public class D {
    public void show(){
      System.out.println("我是父类D的show方法");
    };
}
//继承实现类
public class C extends D implements A,B{
    @Override
    public void showA(){//抽象方法重名重写一次就好
        System.out.println("我是A");
    };
    @Override
    public  void showB(){//抽象方法
        System.out.println("我是B");
    };
    @Override
    public void show(){ //如果父类存在同名方法,优先执行父类。不存在,默认方法重名必须重写。
    }
}

接口的多继承:  接口之间可以相互继承,一个接口能继承另一个或多个接口。

  接口继承使用 extends 关键字,子接口继承父接口的方法,如果默认方法存在重名,则需要重写一次。

interface C extends A,B{
    @Override
    public default void show(){  //接口重写方法时,可以保留default关键字(子类重写不可以保留)。
        System.out.println("我是C");
    };
}

 

温馨提示

  • 如果您对本文有疑问,请在评论部分留言,我会在最短时间回复。
  • 如果本文帮助了您,也请评论关注,作为对我的一份鼓励。
  • 如果您感觉我写的有问题,也请批评指正,我会尽量修改。