实现JAVA多态的方式中可以通过抽象类实现抽象类中的抽象方法,和接口来实现
在面向对象语言中,是来通过类来描述对象的,但是不是所有类都是用来描述对象的,如果一个类没有足够的信息来描述一个具体的对象时,这类就是抽象类。
抽象方法:被abstract修饰,有方法名无方法体的方法
拥有抽象方法的类是抽象类
抽象类特点:
1、抽象类不能被实例化,如果被实例化,编译会报错无法通过。只有抽象类的非抽象子类可以创建对象
2、抽象类中不一定包含抽象方法,但是包含抽象方法的类一定是抽象类
3、抽象类中的抽象方法只是声明,不包含方法体即方法的具体实现功能
4、构造方法,类方法(用static修饰的方法)不能声明为抽象方法
5、抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非子类也是抽象类
6、 抽象方法不能是private的,抽象方法没有加访问限定修饰符时默认是public,同样不可以被final、static修饰,因为抽象方法是要被子类重写的
7、若顺序继承了多个抽象类,那么最后的子类(非抽象类)需要定义前面所有的未被定义的抽象方法
public abstract class Animals {
int age;
String name;
public Animals(int age, String name) {
this.age = age;
this.name = name;
}
public abstract void speak();
public abstract void eat();
}
public abstract class Dog extends Animals{
public Dog(int age, String name) {
super(age, name);
}
public abstract void showKind();
@Override
public void eat() {
System.out.println("吃肉肉");
}
@Override
public void speak() {
System.out.println("汪汪");
}
}
public class Cat extends Animals{
public Cat(int age, String name) {
super(age, name);
}
@Override
public void speak() {
System.out.println("喵喵");
}
@Override
public void eat() {
System.out.println("吃鱼鱼");
}
}
public class Corgi extends Dog{
String kind = "Corgi";
public Corgi(int age, String name) {
super(age, name);
}
/*
*/
@Override
public void eat() {
System.out.println("吃精装狗粮");
}
@Override
public void showKind() {
System.out.println(kind);
}
}
public class Corgi extends Dog{
String kind = "Corgi";
public Corgi(int age, String name) {
super(age, name);
}
/*这种情况下会调用父类中重写的方法
@Override
public void eat() {
System.out.println("吃精装狗粮");
}
*/
@Override
public void showKind() {
System.out.println(kind);
}
}
public class TeatAnimals {
public static void behavior(Animals animals)
{
animals.speak();//只能调用向上所转型的父类的被重写的抽象方法
animals.eat();
}
public static void main(String[] args) {
Corgi corgi = new Corgi(3,"小柯");
Cat cat =new Cat(4,"招财");
behavior(corgi);
behavior(cat);
}
}
因为JAVA中没有多继承,所以通过实现接口来间接的实现多继承
接口是抽象方法的集合,通常以interface来声明,接口不是类而是一种引用类型
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法
接口无法被实例化,可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类
另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象(Java 接口 | 菜鸟教程 (runoob.com))
接口和类的相似之处:
1、接口和类一样,一个接口中可以有很多方法
2、接口文件保存在 .java 结尾的文件中,文件名为接口名,其字节码文件保存在.class结尾的文件中(接口虽然不是类但是编译以后也是.class字节码文件)
3、接口的字节码文件必须与包名称相匹配的目录结构中
接口与类的区别:
1、接口无构造方法,不能被实例化
2、接口中的方法必须都是抽象的(java 8 后default可以用来修饰非抽象的方法)
3、接口一般不包含成员变量,除static和final修饰的变量
4、接口支持多继承
接口的特点:
1、接口中的方法被隐式的指定为 public abstract
2、接口中的变量被隐式的指定为 public static final
3、接口中的方法不能在接口中实现,只能由实现接口的类来实现接口中的方法,重写接口方法时不可以使用default修饰
4、接口和其方法声明时可以不用abstract,因为本身就是隐式抽象的
5、类在实现接口的方法时,不可抛出强制性异常,只能在接口中和继承接口的抽象类中抛出该强制性异常
6、如果实现的接口继承多接口,那么实现接口的类需要实现所有接口中的抽象方法
接口与抽象类的不同:
1、一般情况下,抽象类中可以有非抽象方法,接口不行
2、抽象类中的变量和方法的权限可以改变,接口不可以
3、接口中不能包含静态代码块和静态方法,但是抽象类可以有
4、一个类只能继承一个抽象类,一个类可以实现多个接口
(JDK1.8后,接口里允许有静态方法和方法体了,同时接口允许包含由default修饰的具体实现方法,被称为 默认方法,1.9后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去,详情可学习Java 9 私有接口方法 | 菜鸟教程 (runoob.com))
特殊接口:
标记接口,一个没有任何属性和方法的接口,详情(Java 接口 | 菜鸟教程 (runoob.com))