1.抽象abstract类概述
假设定义一个动物类Animal,其中有一个move方法,用来模拟动物的移动行为,它有多个子类,例如,猫类和鸟类,显然这两种动物的move方法需要不同的实现,也就是它们都需要重写父类的move方法,例如:
class Animal{
public void move(){
System.out.println("Animal move()");
}
}
class Cat extends Animal{
public void move(){
System.out.println("Cat walk");
}
}
class Bird extends Animal{
public void move(){
System.out.println("Bird fly");
}
}
2.
既然子类都需要重写父类的方法,换句话说,就是父类只知道子类有这样的行为,但是不知道子类到底怎么去实现,那为什么不在父类中不用定义这个方法不就行了?父类根本不管这个方法就是了?
如果这样做的话,就不能使用多态了,使用父类的变量根本不能调用子类特有的方法,只能使用子类变量去指向子类对象了,这样就降低了程序的灵活性。
有没有一种办法,既能使用多态,又能省去在父类中实现方法的麻烦?
Java中使用“抽象方法”来解决这个问题,抽象方法的意思就是:只规定方法的签名,并不提供方法的实现,即:没有方法体。
Java规定:只有方法签名,没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
3.抽象类/方法特点
抽象类和抽象方法必须用abstract关键字修饰
- 抽象类定义
abstract class 类名 {}
- 抽象方法定义,在返回值前,或修饰符前加上abstract关键字
- 方法没有方法体,即:没有{}
abstract public void eat();
public abstract void eat();
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类完全可以有成员变量和非抽象成员方法
抽象类不能实例化
抽象类的实例化按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态
抽象类可以有构造方法,抽象方法是用来被子类调用的,程序员不能调用
抽象类的子类--使用extends
- 要么是抽象类,不完全实现其父类的抽象方法
- 要么重写抽象类中的所有抽象方法,这个子类就是一个完全的实现类了,所以可以用来实例化对象
抽象类大数据开发java基础12,抽象方法定义时的非法组合
- private abstract
抽象方法依靠子类去实现,但是私有方法在类外就不能访问,也就无法实现
- final abstract
final修饰的方法不能被重写,而抽象方法就是需要子类实现,矛盾
- static abstract
抽象方法在本类中是没有方法体的,使用类名调用的时候调用的是没有方法体的方法,无作用
4.抽象类的概述:
动物是一个抽象概念,不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
抽象类的特点:
A:抽象类和抽象方法必须用abstract关键字修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
C:抽象类不能实例化
因为它不是具体的。
抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
用于子类访问父类数据的初始化,隐含被虚拟机调用
D:抽象的子类
a:如果不想重写全部抽象方法,该子类是一个抽象类。
b:重写所有的抽象方法,这个时候子类是一个具体的类。
抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
5.抽象类成员的特点
抽象类的成员特点:
成员变量:既可以是变量,也可以是常量。
构造方法:有。用于子类访问抽象类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
抽象类的成员方法特性:
A:抽象方法 强制要求子类做的事情。
B:非抽象方法 子类继承的事情,提高代码复用性。
6.总结,在abstract类中:
成员变量
- 可以是变量,也可以是常量(final)
构造方法
- 有构造方法,但是不能实例化(不能被显式调用,但JVM可以隐含调用)
作用是用于子类访问抽象类数据的初始化
成员方法
- 可以有抽象方法 限定子类必须完成某些动作
- 也可以有非抽象方法,用来提高代码复用性,子类可以继承
7.抽象类的小问题
一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
A:可以。
B:不让创建对象
8.接口interface的引入
抽象类是从多个类中抽象出来的模板,如果将这种抽象进行得更彻底,则可以提炼出来一种更加特殊的“抽象类”--接口,接口里不能包含普通方法,接口里的所有方法都是抽象方法。
接口的概念
一提到接口,会联想到PCI接口,USB接口等等概念,但是这实际上是错误的,当提到PCI接口的时候,指的是主板上的插槽遵守了PCI规范,而主板上的PCI插槽只是PCI接口的实例。
而对于不同型号的主板而言,它们各自的PCI插槽都需要遵守一个规范,遵守这个规范就能保证插在这个插槽的板卡可以和主板正常通信,对于同一个型号的主板而言,它们的PCI插槽要有相同的数据交换方式,相同的实现细节,它们都是同一个类的不同实例,它们的抽象过程如下:
接口只规定PCI能实现的功能:交换数据,供电等等
从图中可以看出,同一个类的内部状态数据,各种方法实现细节等完全相同,类是一种具体实现体。
接口定义了一种规范,接口规定了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定了这批类必须提供某些方法,提供这些方法的类就可以满足实际需要。
接口和前面讲的抽象类非常像,抽象类是规定了一个方法名而已,具体的实现要靠它的实现类。接口也是,接口只规定它的实现类都应该实现的最基本的方法名而已,而实现类首先应该实现这些最基本的方法,然后可以在此基础之上进行扩展。
前面说过,抽象类可以有抽象方法,也可以没有抽象方法,还可以有自己的成员变量和常量。而接口中的方法全都是抽象方法,其中的成员变量全都是常量。
9.接口特点
接口用关键字interface表示
- 格式:interface 接口名 {} //不能使用class关键字了
类实现接口用implements关键字
- 格式:class 类名 implements 接口名 {}
接口没有构造方法,即:接口不能实例化
- 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
接口的子类
- 可以是抽象类,用implements关键字,
abstract class A implements ITest{} //抽象类和接口之间用实现
- 或者还是一个接口,用extends关键字
interface A extends ITest{} //接口和接口之间用继承
- 是一个实现类,实现接口中的所有抽象方法,用implements关键字
class B implements ITest{...} //实现类和接口之间用实现
10.小结:
只有接口和接口之间使用的是extends关键字,抽象类和接口之间,实现类和接口之间都是用的implements关键字
演示接口常规用法:
1.接口不能实例化对象
2.子类如果是实现类的话,就必须实现接口中定义的所有抽象方法
3.子类如果不完全实现接口中的抽象方法,那子类就是抽象类
4.接口和接口之间可以继承--extends
11.接口成员特点
成员变量
- 只能是常量
- 默认修饰符 public static final,其中的任何一个都可以省略,也可以全都省略
构造方法
- 没有,因为接口主要是扩展功能的,而没有具体存在
成员方法
- 只能是抽象方法
- 默认修饰符 public abstract,可以省略其中之一,或者都省略。
void show1(); //public abstract都省略
public void show2();
abstract void show3(); //省略public
public abstract void show4();
12.类与类,类与接口,接口与接口的关系
普通类与普通类--extends
- 继承关系,只能单继承,但是可以多层继承
普通类与抽象类--extends
- 继承关系,只能单继承,但是可以多层继承
普通类与接口,抽象类与接口--implements
- 实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口
- 此时应注意:extends 写在前,implements写在后
接口与接口--extends
- 继承关系,可以单继承,也可以多继承
13.抽象类和接口的区别
定义时使用的关键字
- 抽象类 abstract
- 接口 interface
成员区别
- 抽象类 变量,常量都可以有;抽象方法,非抽象方法都可以有;可以有构造方法
- 接口 只有常量;只有抽象方法;没有构造方法
关系区别
- 类与类 继承,单继承,多层继承
- 普通类与接口 实现,单实现或多实现implements
- 抽象类与接口 实现,单实现,多实现abstract class A implements IA,IB
- 普通类与抽象类 继承,并实现全部抽象方法extends
- 接口与接口 继承,单继承,多继承extends
14.总结:
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/26429.html