抽象类:
定义一个类的时候,常常需要定义一些方法来描述该类的行为特征,但有时候这些方法的实现方式无法确定。
针对这种情况,Java允许在定义方法的时候可以不写方法体,不包含方法体的方法称为抽象方法,用关键字abstract修饰。
当一个类中包含了抽象方法,该类就必须声明为抽象类,abstract修饰。
注意:包含抽象方法的类必须声明为抽象类,但抽象类中可以不包含抽象方法。抽象类是不可以被实例化的。
package day11;
abstract class Animals {
// 抽象类不能实例化,即不能new
String name = "Animals.name";// 成员变量
// abstract String name2;//成员变量不能抽象
public Animals() {
System.out.println("抽象类的构造方法");
}
abstract void d1();// 默认public
// abstract void d9(){}// 抽象类不能带方法体,abstract不能和{}同用
// void d8();// 默认public,不带abstract报错,没有方法体.
void d3() {
};// 默认public非abstract
// final abstract void d7();// abstract不能和final同用
// private abstract void d6();// abstract不能和private同用
protected abstract void d4();// abstract能和protected同用
public abstract void shout();;
// public static abstract void shout2() {}//抽象类abstract不能和static同用
// 抽象类中的成员变量和成员方法非抽象的时候,即不用abstract关键字修饰时,
// 抽象类的继承和普通类的继承是一样的
public void speak() {
System.out.println("抽象类中可以有非抽象方法");
}
public static void ststicMethod() {
System.out.println("抽象类中可以有静态方法");
}
}
class Cat extends Animals {
// 子类(非抽象的子类 )必须实现全部的父抽象类中的抽象方法
public Cat() {
System.out.println("子类的构造方法");
}
@Override
public void shout() {
System.out.println("喵喵喵~");
}
@Override
void d1() {
}
@Override
protected void d4() {
}
}
public class Main {
public static void main(String[] args) {
Cat c1 = new Cat();
c1.shout();// 子类实现的shout()
c1.speak();// 抽象类中的非抽象方法
System.out.println(c1.name);// 抽象类中的成员变量
Animals.ststicMethod();// 抽象类中的静态方法可以通过 抽象类名.方法名()调用
Cat.ststicMethod();// 也可以通过 子类类名.方法名()调用
c1.ststicMethod();
}
}
运行结果:
从运行结果分析,抽象类就是一个特殊的类,里面可以写不带方法体的方法了而已,并且抽象方法前面的abstract不能省略,不能和private、final关键字连用,因为抽象类是要被继承重写实现的。
接口:
如果一个类中的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。
抽象类中方法默认使用public abstract修饰,即抽象方法。
抽象类中的变量默认使用public static final修饰,即常量。
1.8版本之后,允许接口中存在带方法体的方法,要使用default关键字修饰该方法。
一个非抽象类可以使用implement关键字实现某个接口中的所有方法。
抽象类实现接口的时候,可以只实现部分方法。
一个类在继承另一个类的同时还可以实现接口,此时extends关键字必须位于implement关键字之前。