要求父类的某个方法必须被子类覆写,那么就需要将父类的这个方法定义为抽象方法(强制要求被覆写),如果一个类中出现了抽象方法那么这个类必须定义为抽象类,抽象类和抽象方法的定义语法:
定义抽象类:public abstract class 类名{};
定义抽象方法:public abstract 返回值类型 方法名();
【抽象方法没有方法体】
定义一个抽象类
/**
* 定义了一个抽象类
* @author 不是很渣
*
*/
public abstract class Person {
//定义一个普通方法
public void getInfo() {
System.out.println("这是一个普通的成员方法");
}
//定义了两个抽象方法
public abstract void say();
public abstract void eat();
}
可以使用该抽象类实例化一个对象吗?
发现了不能使用抽象类的构造方法实例化对象,如果不能实例化对象那么抽象类中的所有操作(属性和方法)都没有任何意义,因为不能访问,此时可以通过子类来继承抽象类中的操作,让子类对象去调用。
定义抽象类的子类
The type Student must implement the inherited abstract method Person.eat()
此时定义了抽象类的子类,但是要求子类必须覆写父亲的所有抽象方法
public class Student extends Person {
@Override
public void say() {
System.out.println("我是个好孩子!");
}
@Override
public void eat() {
System.out.println("我正在吃饭!");
}
}
这样就不报错了。
使用将父类的方法定义为抽象方法的方式来实现强制要求覆写某个方法的目的(如果某个方法要求强制覆写,将其定义为抽象方法即可)
但是有一种情况可以不要求子类覆写父类的所有抽象方法,如果子类也是一个抽象类的时候可以不覆写父类的抽象方法。
子类是抽象类
public abstract class Student extends Person {
}
此时可以选择性覆写父类的抽象方法
总结:
1.定义抽象类和抽象方法使用的关键字是【abstract】
2.抽象类被叫做一个不完成的类因为它有自己的构造方法,但是却不能直接实例化对象,他的抽象方法没有方法体。
【父类】
public abstract class Person {
//定义一个构造方法
public Person(){
System.out.println("我是父类的构造方法!");
}
//定义一个普通方法
public void getInfo() {
System.out.println("这是一个普通的成员方法");
}
//定义了两个抽象方法
public abstract void say();
public abstract void eat();
}
【子类】
public class Student extends Person {
@Override
public void say() {
// TODO Auto-generated method stub
}
@Override
public void eat() {
// TODO Auto-generated method stub
}
}
public class Hello {
public static void main(String[] args) {
//创建一个父类对象
Person per =new Person();
//创建一个子类对象
Student s =new Student();
}
}
【发现父类对象不能直接创建】
3.如果子类不是一个抽象类那么必须覆写父类的所有抽象方法
面试题:
1.抽象类中可以没有抽象方法吗?
【可以】
2.如果抽象类没有抽象方法,那么可以直接实例化对象吗?
【不可以,因为没有抽象方法他依然是一个抽象】
3.抽象类的方法必须被子类覆写吗?
【不一定,如果子类是一个普通类则必须全部覆写,如果子类是一个抽象类则不强制要求全部覆写父类的抽象方法】
4.抽象类中的抽象方法的abstract关键字可以被省略吗?
【不可以(但是在后面的接口中可以省略】