抽象类跟多态
Posted spyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象类跟多态相关的知识,希望对你有一定的参考价值。
第1章 抽象类
1.1 抽象类概述
使用 abstract关键字修饰的类就叫做抽象类!
Java三大特征
封装
继承
多态
当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具体实现方式,那么这些方法都有具体的方法体。
但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。
分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。
/**
* 描述动物
* abstract 可以定义抽象类
*/
public abstract class Animal {
public String
name;
public int age;
public String sex;
/**
* 定义抽象方法
*/
public abstract void eat();
public void active(){
System.out.println( name + "运动");
}
}
**
* 描述狗
*/
public class Dog extends Animal {
@Override
public void eat() {
System.out.println(name + "啃骨头");
}
public void lookHouse(){
System.out.println("狗看守房子");
}
}
/**
* 描述猫这类事物
*/
public class Cat extends Animal {
@Override
public void eat() {
System.out.println(name + "吃老鼠");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
public class Demo1 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "tom";
cat.sex = "雌";
cat.age = 2;
cat.eat();
Dog dog = new Dog();
dog.name = "小黄";
dog.sex = "雄";
dog.age = 5;
dog.eat();
}
}
运行结果
1.2 抽象类的特点
抽象类的特点:
抽象方法只能在抽象类里面
抽象类和抽象方法必须被abstract修饰
抽象类不能创建对象(不能实例化)
抽象类中可以有非抽象的方法
一个类继承了抽象类要么重写所有的抽象方法,要么他自己是抽象类
1.3 抽象类的成员的特点
A:抽象类的成员特点:
成员变量
可以有成员变量
可以有常量
成员方法
可以有抽象方法
可以有非抽象方法
构造方法
可以有构造方法的,需要对抽象类的成员变量进行初始化
1.4 抽象类案例
1.4.1 老师案例:
老师类
属性:姓名,年龄,性别
行为:讲课
幼儿园老师:
属性:姓名,年龄,性别
行为: 讲课 启蒙教育
java老师:
属性:姓名,年龄,性别
行为:讲课 讲java课程
1.4.2 员工案例
员工类:
属性:姓名,编号,薪水
行为:工作
程序员:
属性:姓名,编号,薪水
行为:写代码工作
经理:
属性:姓名,编号,薪水,奖金
行为:盯着程序员写代码工作
1.5 抽象类的细节
1.5.1 抽象类关键字abstract不可以和哪些关键字共存?
1.private:
私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。
2.final:
抽象类不能和final共存,因为抽象类自身无法创建对象,我们需要通过子类创建对象,一旦抽象类使用final关键字,那么抽象类就没有子类
抽象方法不能和final共存,因为抽象方法后期需要被子类重写,一旦加final无法重写
3.static:
抽象方法不能和static关键字共存,因为一旦加static我们就可以通过类名直接访问抽象方法,由于抽象方法没有方法体,没有任何意义,也不允许这样做
1.5.2 抽象类中是否可以不定义抽象方法?
是可以的,那这个抽象类的存在到底有什么意义呢?不让该类创建对象,方法可以直接让子类去使用
1.5.3 抽象类是否有构造函数?
有,抽象类的构造函数,是由子类的super语句来调用,用于给抽象类中的成员初始化
第2章 接口
2.1 接口的概述
接口是功能的集合,是比抽象类更为抽象的”类”。
接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。
2.2 接口的格式&使用
2.2.1 接口的格式
与定义类的class不同,接口定义时需要使用interface关键字。
定义接口所在的仍为.java文件,虽然声明时使用的为interface关键字的编译后仍然会产生.class文件。这点可以让我们将接口看做是一种只包含了功能声明的特殊类。
定义格式:
public interface 接口名 {
抽象方法1;
抽象方法2;
抽象方法3;
}
2.2.2 接口的使用
接口中的方法全是抽象方法,直接new接口来调用方法没有意义,Java也不允许这样干
类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用implements
其他类(实现类)实现接口后,就相当于声明:”我应该具备这个接口中的功能”。实现类仍然需要重写方法以实现具体的功能。
格式:
class 类 implements 接口 {
重写接口中方法
}
在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。
/**
* 描述动物
* interface 可以定义接口
*/
public interface Animal {
/**
* 定义抽象方法
*/
public abstract void eat();
/**
* 运动
*/
public abstract void active();
}
/**
* 描述鱼这类事物
*/
public class Fish implements Animal {
@Override
public void eat() {
System.out.println("吃蚯蚓");
}
@Override
public void active() {
System.out.println("在水中游着动");
}
}
2.3 接口中成员的特点
1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量,其值不能改变。
2、接口中可以定义方法,方法也有固定的修饰符,public abstract
3、接口不可以创建对象。
4、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。
2.4 接口和类的关系
A:类与类之间:继承关系,一个类只能直接继承一个父类,但是支持多重继承
B:类与接口之间:只有实现关系,一个类可以实现多个接口
C:接口与接口之间:只有继承关系,一个接口可以继承多个接口
2.5 接口的思想
前面学习了接口的代码体现,现在来学习接口的思想,接下里从生活中的例子进行说明。
举例:我们都知道电脑上留有很多个插口,而这些插口可以插入相应的设备,这些设备为什么能插在上面呢?主要原因是这些设备在生产的时候符合了这个插口的使用规则,否则将无法插入接口中,更无法使用。发现这个插口的出现让我们使用更多的设备。
接口的出现方便后期使用和维护,一方是在使用接口(如电脑),一方在实现接口(插在插口上的设备)。例如:笔记本使用这个规则(接口),电脑外围设备实现这个规则(接口)。
2.6 接口优点
A:接口是对外暴露的规则。
B:类与接口的关系是实现。
C:接口的出现降低耦合性。(实现了模块化开发,定义好规则,每个人实现自己的模块,大大提高了开发效率)
2.7 接口和抽象类的异同
A:相同点:
都位于继承的顶端,用于被其他类实现或继承;
都不能直接实例化对象;
都包含抽象方法,其子类都必须覆写这些抽象方法;
B:区别:
1:一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承) 单继承多实现
2:成员变量
抽象类既可以有常量也可以有变量,接口只能有常量
3:成员方法
抽象类既可以有抽象方法也可以有非抽象方法
接口只能有抽象方法
4:构造方法
抽象类有构造方法,子类通过super语句调用
接口没有构造方法
5.抽象类是用来描述某一类事物,接口是用来定义功能规范
2.8 运动员案例
2.8.1 案例代码
第3章 多态
3.1 多态概述
多态是继封装、继承之后,面向对象的第三大特性。
现实生活中同一类事物的同一个功能经常会体现出多种形态,例如动物这一类事物的吃的功能,猫和狗吃东西的时候表现出来的形态不一样,这种现象称之为多态
Java作为面向对象的语言,同样可以描述一个事物的多种形态。
多态指的是同一种类型的变量,在调用不同对象的同一个方法的时候,表现出来的多种形态
多态:父类的变量指向了子类的对象的时候,当我们去调用父类类型中的方法的时候,子类类型不一样就会表现出不同的形态
3.2 多态的定义与使用格式
多态的定义格式:就是父类的引用变量指向子类对象
父类类型 变量名 = new 子类类型();
变量名.方法名();
1:普通类多态定义的格式
父类 变量名 = new 子类();
2:抽象类多态定义的格式
抽象类 变量名 = new 抽象类子类();
3:接口多态定义的格式
接口 变量名 = new 接口实现类();
3.3 多态成员的特点
1 :多态成员变量
当子父类中出现同名的成员变量时,多态调用该变量时:
编译时期:参考的是引用型变量所属的类中是否有被调用的成员变量。没有,编译失败。
运行时期:也是调用引用型变量所属的类中的成员变量。
简单记:编译和运行都参考等号的左边。编译运行看左边。
2:多态成员方法
编译时期:参考引用变量所属的类,如果没有类中没有调用的方法,编译失败。
运行时期:参考引用变量所指的对象所属的类,并运行对象所属类中的成员方法。
简而言之:编译看左边,运行看右边
3.4 多态中向上转型与向下转型
多态的转型分为向上转型与向下转型两种:
向上转型:当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。
使用格式:
父类类型 变量名 = new 子类类型();
如:Person p = new Student();
向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的
使用格式:
子类类型 变量名 = (子类类型) 父类类型的变量;
如:Student stu = (Student) p; //变量p 实际上指向Student对象
3.5 多态的优缺点
多态的优缺点
优点:可以提高可维护性(多态前提所保证的),提高代码的可扩展性
缺点:无法直接访问子类特有的成员
以上是关于抽象类跟多态的主要内容,如果未能解决你的问题,请参考以下文章