1.多态的引入
面向对象有三大特征:封装,继承与多态。多态是面向对象的三大特征之一,指的是在不同的时刻,所表现出的不同的状态。举个简单的例子来说,动物中的猫属于猫类型,具体在创建对象时,可以通过Cat cat =new Cat()的代码来进行实现。同时猫也属于动物类型,按照此种逻辑进行推算的话,可以使用父类的引用去接受子类的对象,具体的实现是:Animal an=new Cat(),这种现象就叫做多态。
2.多态产生的条件以及意义
下面对多态产生的条件作以介绍:
多态的前提 |
---|
1.多态的前提是继承,没有继承,多态也就无从谈起 |
2.多态必须要有方法的重写(不重写也是可以的,但就会失去多态的意义) |
3.多态具体的代码实现是:父类的引用指向子类的对象 |
public class MyTest {
public static void main(String[] args) {
//多态的语法:父类引用指向子类对象
Animal animal = new Cat();
animal.eat();
animal.sleep();
System.out.println("============");
animal = new Dog();
animal.eat();
animal.sleep();
}
}
//父类:将子类中共有的的成员进行抽取
class Animal{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
//子类:猫类
class Cat extends Animal{
public void catchMouse(){
System.out.println("猫抓老鼠");
}
//对父类中的方法进行重写
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫喜欢躺在温暖的地方睡觉");
}
}
//子类:狗类
class Dog extends Animal{
public void lookDoor(){
System.out.println("狗看门");
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗喜欢晚睡");
}
}
输出的结果为:
猫吃鱼
猫喜欢躺在温暖的地方睡觉
============
狗吃骨头
狗喜欢晚睡
多态的意义 |
---|
提高代码的复用性与维护性(靠继承可以进行保障) |
多态提高代码的扩展性 |
下面的案例中体现多态提高代码的扩展性:
public class MyTest {
public static void main(String[] args) {
//多态:父类的引用指向子类的对象
Aniaml aniaml = new Cat();
aniaml.eat();
System.out.println("===============");
aniaml = new Dog();
aniaml.eat();
}
}
//父类
class Aniaml{
public void eat(){
System.out.println("吃饭");
}
}
//子类:猫类
class Cat extends Aniaml{
@Override
public void eat() {
System.out.println("小猫吃鱼");
}
}
//子类:狗类
class Dog extends Aniaml{
@Override
public void eat() {
System.out.println("小狗吃骨头");
}
}
//功能测试类
class AniamlGongJu{
/*多态的程序的扩展性在此有体现
当需要再增加其他动物时,不用在此
对程序进行增加。形参这里给的父类的
引用,体现多态的可扩展性。
*/
public static void test(Aniaml an){
an.eat();
}
}
输出的结果为:
小猫吃鱼
===============
小狗吃骨头
3.多态访问成员的特点
多态的语法为:父类的引用指向子类的对象
多态访问成员的特点 |
---|
多态的形式来访问成员变量,编译看左边(父类),运行看左边(父类) |
多态的形式访问成员方法,如果子类有重写,编译看左边(父类),运行看右边(子类)。运行的结果以子类重写的方法为准。 |
多态的形式访问静态方法,静态方法不参与方法重写,编译看左边(父类),运行看左边(父类) |
多态的语法下的构造方法,是先调用父类的构造方法,先完成父类的数据初始化 |
public class MyTest {
public static void main(String[] args) {
//多态的语法:父类的引用指向子类对象
Fu f = new Zi();
//多态的形式访问成员变量,编译看父类,运行看父类
int num=f.num;
System.out.println(num);//100
/*多态的形式访问成员方法,如果子类有重写,编译
看父类,运行看子类。运行后的结果以子类的重写
后的方法为准
*/
f.show();//子类的show方法执行了
//静态的方法不参与重写(直接可以用类名进行访问)
Fu.test();
}
}
class Fu{
//父类的成员变量
int num=100;
//父类的构造方法
public Fu(){
System.out.println("父类的构造方法执行了");
}
public void show(){
System.out.println("父类的show方法执行了");
}
public static void test(){
System.out.println("父类的静态方法");
}
}
class Zi extends Fu{
//子类的成员变量
int num=500;
public Zi(){
System.out.println("子类的构造方法执行了");
}
@Override
public void show() {
System.out.println("子类的show方法执行了");
}
}
输出的结果为:
父类的构造方法执行了
子类的构造方法执行了
100
子类的show方法执行了
父类的静态方法
4.多态的弊端
多态的存在提高了代码的复用性与维护性,以及提高代码的可扩展性。但多态也存在着弊端,不能访问子类中特有的功能。想要进行访问子类中特有的功能,需要进项向下转型。
public class MyTest {
public static void main(String[] args) {
//多态:父类的引用指向子类的对象
//多态就是向上转型
Fu fu= new Zi();
fu.show();//子类的成员方法
//多态的弊端:就是不能直接访问子类中特有的功能
//fu.test();
//通过向下转型的方式:把父类引用,向下转换为子类型
Zi zi= (Zi) fu;
zi.test();//子类中特有的方法
}
}
//父类
class Fu{
public void show(){
System.out.println("父类的成员方法");
}
}
//子类
class Zi extends Fu{
//子类重写父类中的成员方法
@Override
public void show() {
System.out.println("子类的成员方法");
}
public void test(){
System.out.println("子类中特有的方法");
}
}
5.多态的题目分析题
1.看下面的程序是否有问题,如果没有,说出结果
public class MyTest {
public static void main(String[] args) {
//采用多态的方式,父类的引用指向子类对象
Fu fu = new Zi();
fu.show();//子类的show方法
//多态的形式不能直接访问子类中特有的功能
//fu.method();
Zi zi= (Zi) fu;
zi.method();//zi method
}
}
class Fu{
public void show(){
System.out.println("父类的show方法");
}
}
class Zi extends Fu{
@Override
public void show() {
System.out.println("子类的show方法");
}
public void method(){
System.out.println("zi method");
}
}
输出后的结果为:
子类的show方法
zi method
2.看下面的程序是否有问题。如果没有,说出结果
public class MyTest {
public static void main(String[] args) {
//多态的形式:父类引用指向子类对象
A a = new B();
a.show();//javase
System.out.println("===============");
B b = new C();
b.show();//javaee
}
}
class A{
public void show(){
show2();
}
public void show2(){
System.out.println("java");
}
}
class B extends A{
public void show2(){
System.out.println("javase");
}
}
class C extends B{
public void show(){
super.show();
}
public void show2(){
System.out.println("javaee");
}
}
输出的结果为:
javase
===============
javaee
6.总结
- 多态:一种事物,在不同的时刻所表现出的不同状态
- 多态的前提要有继承关系,语法想表现形式为:父类引用指向子类对象
- 多态的好处:提高代码的复用性与维护性,同时主要提高代码的扩展性
- 多态的弊端:不能直接调用子类特有的功能,想要访问子类特有功能,可以进行向下转型的操作
- 多态访问成员的特点:
- 访问成员变量,编译看左边(父类),运行看左边(父类)
- 访问成员方法,子类重写父类中的方法,编译看左边(父类),运行看右边(子类)
- 访问静态方法,静态方法不参与方法重写,编译看左边(父类),运行看左边(父类)