什么叫抽象类?
如果一种方法在一个类中声明,但这种方法没有实现,也就是说,这是一种空的方法,这种方法被称为抽象方法,它必须使用“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(“物理”); } }
在这里,不要混淆重写和实现抽象方法,实现家庭抽象方法的步骤:
- 继承父类
- 重写(override)抽象的父类方法
子类重写父类抽象法是实现父类抽象法的最后一步,即这里重写的目的是实现父类抽象法。
所以问题是,继承抽象子类需要重写抽象子类中的方法(包括抽象方法和普通方法)吗?我查了一下信息,可以理解:答案是(不一定)
抽象类和抽象方法
- 普通继承不一定要重写父亲的方法。
- 抽象继承,如果子类也是抽象的,就不需要重写父类的方法。如果子类不是抽象的,就要求子类在父类中实现抽象的方法。
- 接口继承。如果是子接口,可以扩展父接口的方法;如果是子抽象类,父接口的方法可以部分或全部实现;如果子类不是抽象类,子类必须实现父接口中定义的所有方法。
正如前面提到的,抽象有抽象方法和普通方法。
那么,这个类别可以只有抽象的方法还是普通的方法呢?答案是肯定的。只有抽象方法的类别必须是抽象的类别。只有普通方法的类别也可以声明为抽象类别!(注意也可以!也就是说,你可以把这个类声明为抽象类,也可以不声明为抽象类) 也就是说,一个类可以在不提供抽象方法的情况下声明为抽象类。
所以问题是,既然一个类中没有抽象的方法,为什么要把这个类声明为抽象类呢?
因为一旦一个类被声明为抽象类,那么这个类就不能直接实例化!
没有抽象方法的抽象类*/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接口的类别都需要改变。但在引入默认方法后,原始类别不需要做任何改变,也可以通过这种方式获得这种默认方法,可以很好地扩展新类别,不影响原始类别