1 抽象类和抽象方法
抽象方法:一个方法没有方法体,由abstract修饰。
一个类中如果有方法是抽象方法,则这个类也要编程抽象类(由abstract修饰)。
一个抽象类中可以有抽象方法(0到n个)也可以有不抽象的方法。
抽象类可以被其他类继承,但子类需要重写所有父类的抽象方法,具体实现抽象方法,否则就把子类也写成抽象类。普通类有的抽象类都有,除此之外抽象类中还能写抽象方法。
public abstract class Person{
public abstract void work();//抽象函数。需要abstract修饰,并分号;结束
}
public class Student extends Person{
public void work(){
System.out.println("学生的工作是学习")
}
}
不可以创建抽象类的对象。但可以创建子类的对象。父类可以引用指向子类的对象
Person p = new Student(); // Person是抽象类,Student是子类
抽象类的作用是在抽象类中定义抽象方法,目的是为子类提供一个通用的模板,子类可以在这个模板基础上进行开发,先实现父类的抽象方法,然后扩展子类自己的内容。抽象类设计避免了子类设计的随意性,通过抽象类,子类的设计变得更加严格,进行了某些程度上的限制,使子类更通用。
抽象类中是否有构造器 ?
抽象类一定有构造器。此时构造器的作用是子类初始化对象的时候会先 super() 调用父类构造器。
抽象类是否能被final修饰?
不能。因为被final修饰的类不能被继承,不能有子类,而抽象类设计的初衷就是给子类继承的。
2 接口
类和接口是同一层次的概念,接口不是类,
所以接口没有构造器,也不能创建对象,但接口可以指向实现类(类似父类引用子类对象)。接口使用interface关键字声明。
interface1 in = new Class1(); // 接口指向实现类
接口中内有:
常量(由public static final 修饰);
抽象方法(由abstract修饰,接口中只能是抽象方法);
非抽象方法(由public default修饰);
静态方法。
如果接口中只能定义抽象方法,若想要修改接口中的内容,则所有实现类都收到影响,因此需要加入非抽象方法。
类和接口的关系是实现关系,类是要实现接口的(implements),一旦实现一个接口,则实现类要重写接口中的全部抽象方法。如果没有全部重写抽象方法,则这个类可以变成一个抽象类。
Java只有单继承,但Java有多实现。一个类继承其他类,只能有一个父类,但可以实现多个接口,写法上是先继承后实现。
可以由 接口名.变量名 或 实现类.变量名访问接口中的变量。
接口与抽象类的区别:
接口不是类;
接口定义好规则,实现类负责实现即可;
都不能实例化;
抽象类有构造器、接口没有;
接口中一般都定义抽象方法,抽象类中不一定是抽象方法。
继承与接口实现:
继承是子类对父类的继承,子类和父类是“is-a”关系,希望对父类代码复用时选择继承;
实现是实现类对接口的实现,实现是“has-a”关系。
// 接口
public interface TestInterface1{
public static final int NUM = 10;
public abstract void a();// 抽象方法
public abstract void b(int num);// 抽象方法
public default void c(){
System.out.println("这是一个非抽象方法,可以不重写也可以重写,,重写时不用加default");
}
public static void d(){
System.out.println("这是一个静态方法,静态方法不能重写");
}
}
//实现类
class Student{
//重写接口中所有抽象方法
public void a(){
System.out.println(TestInterface1.NUM);
}
public void b(int num){
System.out.println(num);
}
}
public class Test{ //使用者
public static void main (String[] args){
//多态场景1: 接口指向实现类
TestInterface1 t = new Student();
//可以由 接口名.变量名 访问接口中的变量
System.out.println(TestInterface1.NUM);
//或 实现类.变量名 访问接口中的变量
System.out.println(t.NUM);
//可以由 接口.super.方法 来调用接口中default修饰的非抽象方法
TestInterface1.super.b();
//由 接口.方法 调用静态方法
TestInterface1.d();
}
}