Java面向对象三大特征之继承和多态
Posted 猿力满满
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面向对象三大特征之继承和多态相关的知识,希望对你有一定的参考价值。
目录
前言
上一篇博客我们介绍了Java面向对象思想以及三大特征之一的封装。本文将介绍面向对象三大特征的剩下两个特征——继承和多态,我个人认为继承和多态是三个特征中比较重要且理解起来稍有难度的两个特征,我将尽可能的用浅显易懂的方式为大家介绍清楚这两个特征。
一、继承
1.基本概述
1)概念及格式
概念:继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。(就像父亲和儿子,儿子继承父亲的一些特征,也拥有自己的一些独有的特征。)
格式:public class 子类 extends 父类 { }
范例:public class Zi extends Fu { }
父类也被称为基类、超类。子类也被称为派生类。
子类的特点:子类可以有父类的内容,子类还可以有自己特有的内容。
代码演示:
package com.itheima_01;
/**
* 父类
*/
public class Fu {
public void show() {
System.out.println("show方法被调用");
}
}
package com.itheima_01;
/**
* 子类
*/
public class Zi extends Fu {
public void method() {
System.out.println("method方法被调用");
}
}
package com.itheima_01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Fu f = new Fu();
f.show();
Zi z = new Zi();
z.method();
z.show();
}
}
2)继承的好处和弊端
好处:
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
弊端:继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性。
3)继承的应用场景
使用继承,需要考虑类与类之间是否存在 is..a 的关系,不能盲目使用继承。
is..a 的关系:谁是谁的一种,例如:老师和学生是人的一种,那人就是父类,学生和老师就是子类。
2.继承中的成员访问特点
1)继承中变量的访问特点
在子类方法中访问一个变量,采用的是就近原则。
- 子类局部范围找
- 子类成员范围找
- 父类成员范围找
- 如果都没有就报错(不考虑父亲的父亲…)
2)继承中构造方法的访问特点
子类中所有的构造方法默认都会访问父类中无参的构造方法。
原因:
- 子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
- 每一个子类构造方法的第一条语句默认都是:super()
如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
- 通过使用 super 关键字去显示的调用父类的带参构造方法
- 在父类中自己提供一个无参构造方法
推荐:自己给出无参构造方法
3)继承中成员方法的访问特点
通过子类对象访问一个方法
- 子类成员范围找
- 父类成员范围找
- 如果都没有就报错(不考虑父亲的父亲…)
4)super关键字
this:代表本类对象的引用
super:代表父类存储空间的标识(可以理解为父类对象引用)
this 和 super 的使用区别:
super内存图:
3.方法重写
1)方法重写概述
概念:子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)。
应用场景:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
Override 注解:@Override用来检测当前的方法,是否是重写的方法,起到【校验】的作用。
代码案例:手机类与新手机类
需求:定义手机类与新手机类,手机类定义call方法,方法输出【给xxx打电话】 (xxx通过参数获取),新手机继承手机类,重写call方法,在原有功能上加入【开启视频通话】,测试类中创建新手机类,并调用call方法。
package com.itheima_06;
/*
手机类
*/
public class Phone {
public void call(String name) {
System.out.println("给" + name + "打电话");
}
}
package com.itheima_06;
/*
新手机
*/
public class NewPhone extends Phone {
/*
public void call(String name) {
System.out.println("开启视频功能");
// System.out.println("给" + name + "打电话");
super.call(name);
}
*/
@Override
public void call(String name) {
System.out.println("开启视频功能");
// System.out.println("给" + name + "打电话");
super.call(name);
}
}
package com.itheima_06;
/*
测试类
*/
public class PhoneDemo {
public static void main(String[] args) {
//创建对象,调用方法
Phone p = new Phone();
p.call("林青霞");
System.out.println("--------");
NewPhone np = new NewPhone();
np.call("林青霞");
}
}
2)方法重写注意事项
- 私有方法不能被重写(父类私有成员子类是不能继承的)
- 子类方法访问权限不能更低(public > 默认 > 私有)
4.Java 中继承的注意事项
1.Java 中类只支持单继承,不支持多继承
错误范例:class A extends B, C { }
2.Java 中类支持多层继承
正确范例:
class A {}
class B extends A{ }
class C extends B{ }
继承代码案例
需求:定义老师类和学生类,找到老师类和学生类当中的共性内容,抽取出一个父类,用继承的方式改写代码,并进行测试。
思路:
- 定义老师类(姓名,年龄,教书())
- 定义学生类(姓名,年龄,学习())
- 共性抽取父类,定义人类(姓名,年龄)
- 定义老师类,继承人类,并给出自己特有方法:教书()
- 定义学生类,继承人类,并给出自己特有方法:学习()
- 定义测试类,写代码测试
代码(子类及测试只演示老师类,学生类同理):
package com.itheima_10;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.itheima_10;
public class Teacher extends Person {
public Teacher() {}
public Teacher(String name,int age) {
// this.name = name;
// this.age = age;
super(name,age);
}
public void teach() {
System.out.println("用爱成就每一位学员");
}
}
package com.itheima_10;
/*
测试类
*/
public class PersonDemo {
public static void main(String[] args) {
//创建老师类对象并进行测试
Teacher t1 = new Teacher();
t1.setName("林青霞");
t1.setAge(30);
System.out.println(t1.getName() + "," + t1.getAge());
t1.teach();
Teacher t2 = new Teacher("风清扬", 33);
System.out.println(t2.getName() + "," + t2.getAge());
t2.teach();
}
}
二、多态
1.多态概述
1)什么是多态?
同一个对象,在不同时刻表现出来的不同形态。
举例
猫 cat = new 猫();
动物 animal = new 猫();
2)多态的前提条件有哪些?
- 要有继承/实现关系
- 要有方法重写
- 要有父类/接口引用指向子类/实现类对象
2.多态中成员访问特点
1)多态中成员变量的访问特点是什么?
编译看左边、运行看左边
比如,动物 animal = new 猫(); “编译看左边”的意思是编译时看语句左边的动物类(父类)里有没有这个变量,“运行看左边”的意思是运行时也是获取动物类(父类)里的这个变量。
2)多态中成员方法的访问特点是什么?
编译看左边、运行看右边
比如,动物 animal = new 猫(); “编译看左边”的意思是编译时看语句左边的动物类(父类)里有没有这个方法,“运行看右边”的意思是运行时实际执行的是猫类(子类)里的重写的方法。
下面是代码案例,大家可以去运行看下结果,这样可以更好的理解多态的成员访问特点。
package com.itheima_02;
public class Animal {
public int age = 40;
public void eat() {
System.out.println("动物吃东西");
}
}
package com.itheima_02;
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
package com.itheima_02;
/*
测试类
*/
public class AnimalDemo {
public static void main(String[] args) {
//有父类引用指向子类对象
Animal a = new Cat();
System.out.println(a.age);
// System.out.println(a.weight);
a.eat();
// a.playGame();
}
}
3.多态的好处和弊端
多态的好处:提高了程序的扩展性。
具体体现:定义方法时,如果将父类型作为参数,在使用方法时,可以传递任意子类对象。
多态的弊端:不能使用子类特有的成员。
4.多态中的转型
1)多态中的向上转型
父类引用指向子类对象其实就是向上转型。例如:
Animal a = new Dog();
2)多态中的向下转型
将父类型的引用转换成具体的子类对象。转换格式:
子类 对象名 = (子类)父类引用;
向下转型解决了多态的弊端。
3)多态转型内存图解
狗强制转换成猫会出现 ClassCastException(类型转换异常)。
多态代码案例
需求:请采用多态的思想实现猫和狗的案例,并在测试类中进行测试。
代码(测试类中只测试了Cat类,Dog类小伙伴们可自行测试):
package com.itheima_06;
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("动物吃东西");
}
}
package com.itheima_06;
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
package com.itheima_06;
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
package com.itheima_06;
/*
测试类
*/
public class AnimalDemo {
public static void main(String[] args) {
//创建猫类对象进行测试
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
a = new Cat("加菲", 5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
}
}
总结
关于Java面向对象三大特征中的继承和多态本文就介绍到这里。文章都是博主辛辛苦苦牺牲个人时间写出来的,希望喜欢的朋友能点个赞支持一下,博主感激不尽!文章如有不足的地方请各位小伙伴们多多包涵,有任何问题都可以在评论区指正或私聊我哦!
以上是关于Java面向对象三大特征之继承和多态的主要内容,如果未能解决你的问题,请参考以下文章