一、抽象类(abstract)

        随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一·般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

说明:子类的对象都已经很具体了,什么功能都能实现了,完全不用再创建父类的对象了,这样的父类,就成了抽象类。

1.1 abstract关键字

      abstract关键字只能用来修饰类和方法。(不能修饰属性,构造器、final等)

(1)abstract 修饰类    即抽象类

abstract修饰类以后,这个类就成了抽象类,即不能实例化对象的类了。所有的事情交给他的子类去做,所以抽象类一定有子类,实例化子类的对象去完成相关开发操作

语法:  

    【权限修饰符】 abstract class 类名 {}

说明:虽然抽象类没法实例化了,但是还是需要提供构造器(区分接口,接口没有构造器,就是因为没子类,又没法实例化),因为抽象类的子类会通过super继承这个抽象类的属性和方法。

(2)abstract 修饰方法  抽象方法

       abstract修饰方法以后,这个方法就成了抽象方法,即只有方法声明,没有方法体。抽象方法的方法体是留给后代去实现的,因此,后代必须重新该抽象方法,除非后代继续是抽象类。直到后代重写了父辈们的所有抽象类方法后,后代才可以实例化对象。换句话说,如果子类没有写完父辈的所有抽象方法,那么该子类也是抽象类(必须用abstract修饰)。

语法:【权限修饰符】 abstract 返回值类型 方法名(形参列表);  //注意 没有{ },即没有方法体

说明:既然没有方法体,意味着对象或类没法调用该抽象方法,自然意味着抽象方法一定要在抽象类里面,即有抽象方法的类一定是抽象类。但是抽象类中可以没有抽象方法,抽象类只是不让这个类造对象而已。

          既然必须在子类重写抽象方法,显然,抽象类不允许是私有private,要不其他类根本就看不到。

         同理,抽象方法不允许是static的,因为static方法根本不能重写,类方法各是各的,不会覆盖。(因为static是类方法,每个类都可以有多个子类,子类继承父类方法的时候,先从静态开始,没法覆盖父类方法的,所以不能重写)。

语法:public abstract 返回值类型 方法名();  //注意,抽象方法没有方法体,所以没有大括号{}

(3)抽象类使用场景

    比如求几何图形面积。父类就是几何图形,定义长宽高,体积,面积。但是由于不知道几何图形是啥,所以没法写他的面积公式。就可以把父类几何图形写成抽象类,让子类(具体的矩形,圆,三角形),来重写面积,周长公式。

   或者比如乘坐某交通工具去美国,交通工具的燃油消耗率,行驶时间,都是根据具体交通工具而异,因此抽象交通工具,燃油消耗率,行驶时间等方法,让子类(具体的飞机,轮船),来重写这些方法。

抽象类具有多态性:即可以      抽象类  类名 = new 子类(); 然后  类名.子类方法();

  扩展:匿名子类 (综合匿名对象)

所谓匿名,就是只能调用一次,就是为了省事。

匿名子类,就是一个没有名字的子类。抽象类 + 重写抽象类中的方法,就成了一个匿名子类。

语法:  抽象父类  类名 = new 抽象父类空参构造器(){   //子类什么名字不知道,这里的类名是父类类型,多态性体现

抽象父类中的抽象方法(形参列表){方法体;}  //匿名子类,需要重写完抽象方法后,才可实例化出类名

}

说明:这里的父类类名用了多态,其实实例化的是子类对象,不过子类没有名字。匿名子类可以综合匿名对象一起使用,形成一个大匿名,更省事。

exp:某方法(new 抽象类(){  //main中的某方法,直接调用一个匿名子类的匿名对象

抽象方法1()  //匿名子类的匿名对象需要完成抽象类的抽象方法

抽象方法2(){

})

二、接口(Interface)

       一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是, Java不支持多重继承。有了接口,就可以得到多重继承的效果。另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a(篮球运动员is a 运动员)的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接,但他们并不是is-a关系,而是has-a 关系,比如跨栏运动员和大学生都具备学习的技能,但显然学习技能不是他们的父类。飞机、风筝、热气球都可以飞等等。这种has-a关系,就可以用接口。

JAVA基础 面向对象(五)抽象类 接口 内部类

 

·    接口就是规范,定义的是一组规则,体现了现实世界中“如果你是. 则必须能.”的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系。接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。

2.1 接口的使用    interface关键字

在java中,接口和类是并列关系,(可以想象成接口是一种特别的类)

接口中,只能定义全局常量和抽象方法(JDK7以前 稳定版),静态方法、默认方法(JDK8以后)。

一个类可以实现多个接口。

接口可以继承接口,并且可以多重继承。

接口也能体现多态性。即  接口 类名 = new 实现类();

全局常量:public static final 声明的常量

抽象方法:public abstract 声明的方法

语法:  interface 接口名 【extends 接口1,接口2...】{  //接口可以继承,并且是多重继承

【public static final】 数据类型 变量名 【=默认值】;//由于接口中只能是全局常量,因此public static final 可以省略

【public abstract】返回值类型 方法名();//抽象方法没有方法体,所以没有大括号

}

 说明:接口中不能定义构造器,因为接口是has-a关系,没有子类,同时意味着接口不可以实例化(又没子类,又不能实例化,那自然不用构造器了)。为了实现接口的价值,java让类(非子类)去实现接口的价值(implements),这个类就是实现类。如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化。如果实现类没有覆盖完接口中的所有方法,则此实现类仍为抽象类。

语法:class 类名 【extends 父类 】implements 接口1【,接口2...】{ }

exp: interface Flyable{

int MAX_SPEED = 7900;  //省略了【public static final】 

void abstract void fly(); //抽象方法fly(),没有大括号,等实现类来重写。省略了【public abstract】

}

class Plane implements Flyable{  //实现类Plane

public void fly(){    //重写接口中的fly()方法,此时可以构造对象

System.out.println("蝴蝶飞飞");}

Java类可以实现多个接口。

 

相关文章: