8.Java面向对象-抽象类、接口
一、抽象类的概述及其特点
A:抽象类概述
回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
为什么呢?因为,我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。
所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
B:抽象类特点
a:抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();
b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
用于子类访问父类数据时的初始化
d:抽象类不能直接实例化那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
e:抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法
package org. westos. java9;
public abstract class Animal {
int age;
String name;
public abstract void eat ( ) ;
public abstract void sleep ( ) ;
public void show ( ) {
System. out. println ( "animal show" ) ;
}
}
abstract class demo extends Animal {
public abstract void demo ( ) ;
}
class demozi extends demo {
@Override
public void eat ( ) {
}
@Override
public void sleep ( ) {
}
@Override
public void demo ( ) {
}
}
class Dog extends Animal {
@Override
public void eat ( ) {
System. out. println ( "dog eat" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "dog sleep" ) ;
}
}
package org. westos. java9;
public class Test {
public static void main ( String[ ] args) {
Animal dog= new Dog ( ) ;
System. out. println ( dog. age) ;
System. out. println ( dog. name) ;
dog. eat ( ) ;
dog. sleep ( ) ;
dog. show ( ) ;
}
}
二、抽象类的成员特点
A:抽象类的成员特点
a:成员变量:既可以是变量,也可以是常量。
b:构造方法:有。
用于子类访问父类数据的初始化。
c:成员方法:既可以是抽象的,也可以是非抽象的。
B:案例演示
抽象类的成员特点
C:抽象类的成员方法特性:
a:抽象方法 强制要求子类做的事情。
b:非抽象方法 子类继承的事情,提高代码复用性。
三、抽象类中的面试题
A:面试题1
一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
答案: 可以 . 不能创建对象.
B:面试题2
abstract不能和哪些关键字共存?
private 冲突 (私有不能继承,则不能重写)
final 冲突 (final修饰类不能被继承,不能继承,也就意味着不能被重写,修饰方法不能被重写)
static 不能共存 无意义 (static修饰的方法不参与重写)
四、接口的概述及其特点
A:接口概述
继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了。
但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。
而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。
所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可
B:接口特点
a:接口用关键字interface表示 格式: interface 接口名 {}
b:类实现接口用implements表示 格式: class 类名 implements 接口名 {}
c:接口不能实例化
那么,接口如何实例化呢?
按照多态的方式来实例化。
d:接口的子类
a:可以是抽象类。但是意义不大。
b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
package org. westos. java9;
public interface Jump {
public abstract void show ( ) ;
public default void show2 ( ) {
System. out. println ( "default show2" ) ;
}
public static void show3 ( ) {
System. out. println ( "static show3" ) ;
}
}
package org. westos. java9;
public abstract class Animal {
public abstract void eat ( ) ;
public abstract void sleep ( ) ;
}
package org. westos. java9;
public class Tiger extends Animal implements Jump {
@Override
public void eat ( ) {
System. out. println ( "tiger eat" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "tiger sleep" ) ;
}
@Override
public void show ( ) {
System. out. println ( "tiger show" ) ;
}
}
package org. westos. java9;
public abstract class AbsTiger extends Animal implements Jump {
public abstract void abstiger ( ) ;
}
class Demo extends AbsTiger {
@Override
public void abstiger ( ) {
}
@Override
public void eat ( ) {
}
@Override
public void sleep ( ) {
}
@Override
public void show ( ) {
}
}
package org. westos. java9;
public class Test {
public static void main ( String[ ] args) {
Animal tiger1= new Tiger ( ) ;
tiger1. sleep ( ) ;
tiger1. eat ( ) ;
Jump tiger2= new Tiger ( ) ;
tiger2. show ( ) ;
tiger2. show2 ( ) ;
Jump. show3 ( ) ;
Tiger tiger = new Tiger ( ) ;
tiger. eat ( ) ;
tiger. sleep ( ) ;
tiger. show ( ) ;
tiger. show2 ( ) ;
}
}
五、接口的成员特点
A:接口成员特点
成员变量;只能是常量,并且是静态的。
默认修饰符:public static final
建议:自己手动给出。
构造方法:接口没有构造方法。
成员方法:只能是抽象方法。
默认修饰符:public abstract
建议:自己手动给出。
package org. westos. java9;
public interface Jump {
public static final int num= 5 ;
int a= 2 ;
public abstract void show ( ) ;
void show2 ( ) ;
}
六、类与类,类与接口,接口与接口的关系
A:类与类,类与接口,接口与接口的关系
a:类与类:
继承关系,只能单继承,可以多层继承。
b:类与接口:
实现关系,可以单实现,也可以多实现。
并且一个类,还可以在继承一个类的同时实现多个接口。
c:接口与接口:
继承关系,可以单继承,也可以多继承。
B:案例演示
类与类,类与接口,接口与接口的关系
package org. westos. java9;
public class Test {
public static void main ( String[ ] args) {
Demo zi= new Demo2 ( ) ;
zi. demoFu1 ( ) ;
zi. demoFu2 ( ) ;
zi. demoZi ( ) ;
}
}
interface DemoFu1 {
void demoFu1 ( ) ;
}
interface DemoFu2 {
void demoFu2 ( ) ;
}
interface DemoZi extends DemoFu1 , DemoFu2{
void demoZi ( ) ;
}
class Demo implements DemoFu1 , DemoFu2, DemoZi{
@Override
public void demoFu1 ( ) {
System. out. println ( "fu1" ) ;
}
@Override
public void demoFu2 ( ) {
System. out. println ( "fu2" ) ;
}
@Override
public void demoZi ( ) {
System. out. println ( "zi" ) ;
}
}
class Demo2 extends Demo implements DemoFu1 , DemoFu2, DemoZi{
@Override
public void demoFu1 ( ) {
System. out. println ( "zi1" ) ;
}
@Override
public void demoFu2 ( ) {
System. out. println ( "zi2" ) ;
}
@Override
public void demoZi ( ) {
System. out. println ( "zizi" ) ;
}
}
七、抽象类和接口的区别
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:全部是公共的静态常量 public static final
成员方法:只可以抽象 JDK1.8之后可以定义 default修饰的方法,可以给出功能的具体实现,子类可以继承下去用,JDK1.8之后在接口中也可以定义静态方法
B:关系区别
类与类
继承,单继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承
C:设计理念区别
抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
注意:JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用
JDK1.8之后在接口中也可以定义静态方法
八、猫狗案例加入跳高功能分析及其代码实现
package org. westos. java9;
public interface Jump {
void show ( ) ;
}
package org. westos. java9;
public abstract class Animal {
private int age;
private String name;
public int getAge ( ) {
return age;
}
public void setAge ( int age) {
this . age = age;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public abstract void eat ( ) ;
public abstract void sleep ( ) ;
public Animal ( int age, String name) {
this . age = age;
this . name = name;
}
public Animal ( ) {
}
}
package org. westos. java9;
public class Cat extends Animal {
@Override
public void eat ( ) {
System. out. println ( "cat eat" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "cat sleep" ) ;
}
public Cat ( int age, String name) {
super ( age, name) ;
}
public Cat ( ) {
super ( ) ;
}
}
package org. westos. java9;
public class TomCat extends Cat implements Jump {
@Override
public void eat ( ) {
System. out. println ( "tom eat" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "tom sleep" ) ;
}
@Override
public void show ( ) {
System. out. println ( "tom jump" ) ;
}
public TomCat ( int age, String name) {
super ( age, name) ;
}
public TomCat ( ) {
super ( ) ;
}
}
package org. westos. java9;
public class Test {
public static void main ( String[ ] args) {
Animal tom1= new TomCat ( ) ;
tom1. eat ( ) ;
tom1. sleep ( ) ;
Jump tom2= new TomCat ( ) ;
tom2. show ( ) ;
TomCat tom3 = new TomCat ( 5 , "tom" ) ;
System. out. println ( tom3. getAge ( ) ) ;
System. out. println ( tom3. getName ( ) ) ;
tom3. eat ( ) ;
tom3. sleep ( ) ;
tom3. show ( ) ;
}
}