抽象类和接口
1.抽象类
1) 抽象类与抽象方法
抽象类中不一定要包含抽象方法:
abstract class animal{
public void eat(){
System.out.println("animal.eat()");
}
// public abstract void sleep();
}
包含了抽象方法的类必须声明为抽象类:
//class省略abstract会报错
abstract class animal{
public void eat(){
System.out.println("animal.eat()");
}
public abstract void sleep();
}
2) 抽象方法与一般方法
抽象方法不能直接实例化,必须通过子类实例化
abstract class animal{
public void eat(){
System.out.println("animal.eat()");
}
//报错
public abstract void sleep(){}
}
3) 抽象类一一般父类
一般父类的方法可以直接被实例化,所以也不一定要重写,而抽象类中的抽象方法必须要重写。所以抽象方法一定程度上也起到了提醒的作用。
abstract class animal{
public void eat(){
System.out.println("animal.eat()");
}
public abstract void sleep();
}
class tiger extends animal{
//不重写会报错
public void sleep(){
System.out.println("tiger.sleep()");
}
}
2.接口
1) 接口由全局变量和公共方法组成
interface pet{
public static int cat = 100;
public void playboll();
//下面会报错
// public void playboll2(){
//
// }
}
2) 接口也必须通过子类实例化
interface pet{
public static int cat = 100;
public void playboll();
//下面会报错
// public void playboll2(){
//
// }
}
class catPet extends animal implements pet{
public void playboll(){
System.out.println("catPet.playboll()");
}
}
class dogPet extends animal implements pet{
public void playboll(){
System.out.println("dogPet.playboll()");
}
}
3)接口可以被多继承,这是区别于一般父类的重要特点。
A: 一个接口可以继承多个接口
B:一个类也可以继承多个接口
class animal{
public void eat(){
System.out.println("animal.eat()");
}
public void sleep(){
System.out.println("animal.sleep()");
}
}
interface pet{
public void play();
}
interface machine{
public void work();
}
interface machineDog extends pet,machine{
}
class machinePetDog extends animal implements pet,machine{
public void play(){};
public void work(){};
}
3.抽象类与接口区别
首先抽象类与其子类代表的是父与子的关系,关系是"子类是父类"的关系。 举例动物设计为抽象类,有公共的eat(),sleep()方法,那么老虎
是动物,老虎子类在继承后动物父类也会有上述两个方法, 同时还会有自己的catchs捕猎方法。 而接口的产生是由于子类可以扮演不同的角色,
比如宠物狗是动物,它有宠物狗特有的行为,在继承父类之后如何实现这个特殊的行为呢,有下面几个方法:
A:直接在实现类中加上宠物方法, 缺点是无法实现多态,比如宠物的玩耍在不同动物的实现类中的方法名会不同,无法实现多态
class animal{
public void eat(){
System.out.println("animal.eat()");
}
public void sleep(){
System.out.println("animal.sleep()");
}
}
class mypet1 extends animal{
public void petPlayBall(){
System.out.println("mypet1.petPlayBall()");
}
}
class mypet2 extends animal{
public void petRollBall(){
System.out.println("mypet1.petRollBall()");
}
}
B:把宠物的玩耍方法,加入到父类中,缺点很明显,一些动物不是宠物狗,不应该出现一些宠物狗的方法。
class animal{
public void eat(){
System.out.println("animal.eat()");
}
public void sleep(){
System.out.println("animal.sleep()");
}
public void sajiao(){
System.out.println("animal.sajiao()");
}
}
class tiger extends animal{
}
public class abs{
public static void main(String[] args) {
tiger tiger1 = new tiger();
tiger1.sajiao();
}
}
C:把宠物的玩耍方法,加入到父类中,同时设置为抽象的,强迫每个动物去覆盖。 缺点:一些动物没有宠物狗的行为,为什么还要去覆盖。
abstract class animal{
public void eat(){
System.out.println("animal.eat()");
}
public void sleep(){
System.out.println("animal.sleep()");
}
public abstract void sajiao();
}
class tiger extends animal{
public void sajiao(){
}
}
针对上面的问题,如果有一个所有宠物都遵循的规则,这个规则中包含基本的玩耍方法,其他方法可以重写,这个时候就有了接口。
class animal{
public void eat(){
System.out.println("animal.eat()");
}
public void sleep(){
System.out.println("animal.sleep()");
}
}
interface pet{
public void playboll();
}
class catPet extends animal implements pet{
public void playboll(){
System.out.println("catPet.playboll()");
}
}
class dogPet extends animal implements pet{
public void playboll(){
System.out.println("dogPet.playboll()");
}
}
4.final 关键字
final定义的变量不可改变;
final修饰的方法不能够被重写;
final修饰的类不能被继承;
5.类和方法不加修饰符的问题
1) 类如果不写访问修饰符是friendly (只有同一包中的类可以访问, 其他没有访问权限)
2) 类的成员变量不写修饰符是friendly (只有本类和同一包中的类可以访问, 其他没有访问权限)
2) 而方法不写访问修饰符是private (只能在本类使用, 其他都不行)