当前位置: 首页 > 图灵资讯 > 技术篇> 学习笔记一:接口与继承(抽象类)

学习笔记一:接口与继承(抽象类)

来源:图灵教育
时间:2023-04-28 09:27:08

 

什么叫抽象类?

如果一种方法在一个类中声明,但这种方法没有实现,也就是说,这是一种空的方法,这种方法被称为抽象方法,它必须使用“abstract”修饰符!当一个类包含抽象方法时,这个类必须是“abstract修饰符声明为抽象类!

抽象类比普通类更普遍。这是什么意思?在java的所有类别中,object是最普遍的类别。人们把它作为其他类别的基本类别,而不是特定的例子类别。

例如:为英雄Hero增加抽象方法attack,并将Hero声明为abstract。有三类:法术英雄APHero、物理英雄ADHero、物理英雄ADAPHero; 都是Hero的子类,继承了Hero的属性和方法。但是这三类的attack方法肯定不一样,实现如下:

Hero.java

/*Hero类是三类父类*///包省略publicc abstract class Hero{//因为Hero类含有抽象方法,因此,必须将abstract添加为抽象String name;float hp;float armor;int moveSpeed;public static void main(String[] args) {}// attack///// 需要实现attack方法publicc,hero子类 abstract void attack();///空法体}

ADHero.java

/*物理英雄*//public class ADHero extends Hero{public void physicAttack() {System.out.println(“物理”);}@Overridepublic void attack() {physicAttack();}}

APHero.java

/*法术英雄*//public class APHero extends Hero{@Overridepublic void magicAttack() {System.out.println(“魔法”);}@Overridepublic void attack() {magicAttack();}}

ADAPHero.java

/*可物英雄*///*可物英雄 public class ADAPHero extends Hero{     @Override    public void attack() {        System.out.println(”物理可以进行,也可以进行魔法”);    }     public void magicAttack() {        System.out.println(“魔法”);    }     public void physicAttack() {        System.out.println(“物理”);    } }

在这里,不要混淆重写和实现抽象方法,实现家庭抽象方法的步骤:

  1. 继承父类
  2. 重写(override)抽象的父类方法

子类重写父类抽象法是实现父类抽象法的最后一步,即这里重写的目的是实现父类抽象法。

所以问题是,继承抽象子类需要重写抽象子类中的方法(包括抽象方法和普通方法)吗?我查了一下信息,可以理解:答案是(不一定)

  1. 普通继承不一定要重写父亲的方法。
  2. 抽象继承,如果子类也是抽象的,就不需要重写父类的方法。如果子类不是抽象的,就要求子类在父类中实现抽象的方法。
  3. 接口继承。如果是子接口,可以扩展父接口的方法;如果是子抽象类,父接口的方法可以部分或全部实现;如果子类不是抽象类,子类必须实现父接口中定义的所有方法。
抽象类和抽象方法

正如前面提到的,抽象有抽象方法和普通方法。

那么,这个类别可以只有抽象的方法还是普通的方法呢?答案是肯定的。只有抽象方法的类别必须是抽象的类别。只有普通方法的类别也可以声明为抽象类别!(注意也可以!也就是说,你可以把这个类声明为抽象类,也可以不声明为抽象类) 也就是说,一个类可以在不提供抽象方法的情况下声明为抽象类。

所以问题是,既然一个类中没有抽象的方法,为什么要把这个类声明为抽象类呢?

因为一旦一个类被声明为抽象类,那么这个类就不能直接实例化!

没有抽象方法的抽象类*/public abstract class Hero {    String name;    float hp;    float armor;    int moveSpeed;           public static void main(String[] args) {        //虽然没有抽象的方法,但一旦声明是抽象的,就不能直接实例化        Hero h= new Hero();//报错(具体如下图所示)    }          }

例如,我有一个类,它没有抽象的方法,但是,我不希望它能直接实例化。此时,我可以将此类声明为抽象类。![普通类实例化不会报错](https://img-blog.csdnimg.cn/20200614175839646.png#pic_left =300x100)![在此插入图片描述](https://img-blog.csdnimg.cn/20200614180219684.png#pic_left =300x100)

抽象与界面的区别

区别1:子类只能继承一个抽象类,不能继承多个子类可以实现多个接口的差异2:public可以定义为抽象类,protected,package,private静态和非静态属性final和非final属性,但界面中声明的属性只能是public静态final,即使在此界面中没有明确的声明

public interface AP {    public static final int resistPhysic = 100;//物抗         //即使没有显式声明,resistmagic也是 public static final    //但仍默认为public static final    int resistMagic = 0;//法抗         public void magicAttack();//法术}
注:默认方法

抽象物理方法是一种常见的方法。界面中的物理方法称为默认方法

默认方法是JDK8的新特性,指接口也可以提供特定的方法,而不是以前,只能提供抽象方法 该接口增加了默认方法 revive,这种方法有实现体,并被声明为default

public interface Mortal {    public void die();//英雄死亡     default public void revive() {        System.out.println(“本英雄复活”);    }}

为什么会有默认的方法?

假设没有默认方法的机制,如果你想为Mortal添加一种新的方法,那么所有实现Mortal接口的类别都需要改变。但在引入默认方法后,原始类别不需要做任何改变,也可以通过这种方式获得这种默认方法,可以很好地扩展新类别,不影响原始类别