解耦 多态性 java_Java的多态浅谈

概述

Java的四大基本特性:抽象,封装,继承和多态。其中,抽象,封装,继承可以说多态的基础,而多态是封装,继承的具体表现。如果非要用专业术语来描述什么是多态的话

多态是指程序中定义的引用变量所指向具体类型和通过该引用变量发出的方法调用在编译的时候并不确定,而是程序运行期间才确定,就是说一个引用变量到底指向哪一个类的实例对象,该引用变量发出的方法调用哪一个类的中的方法,必须在程序运行期间才能确定。

记得大学时老师讲多态举的一个例子:上课铃响了,同学们都回各自教室上课,这就是多态。这就完了?如果是刚接触编程的同学来说,估计都懵逼了,我们那时就是这种状态。接下来我们用代码实现下老师说的意思。

多态实例

//上课铃响了

public classRing

{public voidringSound()

{

System.out.println("我是铃声!!!");

}

}

1班的同学听到铃声回去上语文课

public class ClassRoom1 extendsRing

{public voidringSound()

{

System.out.println("classRoom1的同学听到铃声上语文了!!!");

}

}

2班的同学听到铃声回去上英语课

public class ClassRoom2 extendsRing

{public voidringSound()

{

System.out.println("classRoom2的同学听到铃声上英语了!!!");

}

}

Main类

public classMain

{public static voidmain(String[] args)

{

Ring ring= newClassRoom1();

Ring ring1= newClassRoom2();

ring.ringSound();

ring1.ringSound();

}

}

输出

classRoom1的同学听到铃声上语文了!!!

classRoom2的同学听到铃声上英语了!!!

这就是一个简单的的多态例子,我们从中不难发现,多态存在的几个关键点,

有继承关系(extends)

子类重写父类方法(ringSound)

父类引用指向子类对象 Ring ring = newClassRoom1()

现在我们改下例子,看出现什么情况

public classRing

{public static voidringSound()

{

System.out.println("我是铃声!!!");

}

}

这时发现ClassRoom1 和 ClassRoom2 都报错了,那我们也给他们都加上static

public class ClassRoom1 extendsRing

{public static voidringSound()

{

System.out.println("classRoom1的同学听到铃声上语文了!!!");

}

}

ClassRoom2类

public class ClassRoom2 extendsRing

{public static voidringSound()

{

System.out.println("classRoom2的同学听到铃声上英语了!!!");

}

}

预编译没报错了,那么输出应该是刚才的结果,main函数跑起来,输出

我是铃声!!!

我是铃声!!!

可以发现,结果并不是我们所想的那样。我们可以得出一个结论:在Java中static修饰的函数不能被子类重写。

其实Java中,父类含有一个静态函数,而且在他的子类也同样有一个返回类型,函数名,参数列表都相同的静态函数,子类实际上只是将父类中的该同名函数进行隐藏,而非重写,他们两个是完全没有关系的函数,所以他们的行为并不具有多态性。

注意:就是被final修饰的父类函数是无法被重写和private修饰的父类函数无法被继承。这是Java的规定,就不在举例说明

多态的作用

说了这么多,多态有什么作用

解耦,各种设计模式大多是基于多态实现的

复用性,子类处理父类即可

扩充和维护

多态缺点:不能使用子类的特有属性和行为。

多态分类

为了确定执行多态函数的哪一个,所以有两种情况:编译时多态,运行时多态

函数重载都是编译时多态,根据实际参数的数据类型,个数和顺序,Java在编译时就能够确定执行重载函数中的哪一个。

函数重写表现出两种多态性,当对象引用本类实例时,为编译时多态,否则为运行时多态。

public classRing

{public voidringSound()

{

System.out.println("我是铃声!!!");

}

}

Main类

public classMain

{public static voidmain(String[] args)

{

ClassRoom2 ring1= new ClassRoom2();//编译时多态,执行Ring类的ringSound

ring1.ringSound(); //编译时多态,执行ClassRoom2 类的ringSound

Ring ring= newClassRoom2();

ring.ringSound();//运行时多态,是运行Ring的 ringSound 还是 ClassRoom2 类的ringSound 只有运行时在确定。

}

花木兰替父亲花弧从军。那么这时候花木兰是子类,花弧是父类。花弧有自己的成员属性年龄,姓名,性别。花木兰也有这些属性,但是很明显二者的属性完全不一样。花弧有自己的非静态成员方法‘骑马杀敌’,同样花木兰也遗传了父亲一样的方法‘骑马杀敌’。花弧还有一个静态方法‘自我介绍’,每个人都可以问花弧姓甚名谁。同时花木兰还有一个自己特有的非静态成员方法‘涂脂抹粉’。但是,现在花木兰替父从军,女扮男装。这时候相当于父类的引用(花弧这个名字)指向了子类对象(花木兰这个人),那么在其他类(其他的人)中访问子类对象(花木兰这个人)的成员属性(姓名,年龄,性别)时,其实看到的都是花木兰她父亲的名字(花弧)、年龄(60岁)、性别(男)。当访问子类对象(花木兰这个人)的非静态成员方法(骑马打仗)时,其实都是看到花木兰自己运用十八般武艺在骑马打仗。当访问花木兰的静态方法时(自我介绍),花木兰自己都是用她父亲的名字信息在向别人作自我介绍。并且这时候花木兰不能使用自己特有的成员方法‘涂脂抹粉’。  -----------多态中的向上造型

那么终于一将功成万骨枯,打仗旗开得胜了,花木兰告别了战争生活。有一天,遇到了自己心爱的男人,这时候爱情的力量将父类对象的引用(花弧这个名字)强制转换为子类对象本来的引用(花木兰这个名字),那么花木兰又从新成为了她自己,这时候她完全是她自己了。名字是花木兰,年龄是28,性别是女,打仗依然那样生猛女汉子,自我介绍则堂堂正正地告诉别人我叫花木兰。OMG!终于,终于可以使用自己特有的成员方法‘涂脂抹粉’了。从此,花木兰完全回到了替父从军前的那个花木兰了。并且和自己心爱的男人幸福的过完了一生。  ------多态中的向下转型

c89b588d1da49a27e1324808d8a9e6f3.png

花弧

public classHuaHu

{int age = 60;

String name= "花弧";

String sex= "男";public voidhorseKillEnemy()

{

System.out.println("骑马杀敌");

}public static voidsuggest()

{

System.out.println("我叫花弧");

}

}

花木兰

8cf63c4dd0593c4ce6eb57c0b8aa7215.png

public class HuaMuLan extendsHuaHu

{

String name= "花木兰";int age = 28;

String sex= "女";public voidhorseKillEnemy()

{

System.out.println("花木兰骑马杀敌");

}public voidPrettify()

{

System.out.println("花木兰涂脂抹粉");

}

}

替父从军

public classMain

{public static voidmain(String[] args)

{//替父从军

HuaHu huaHu = newHuaMuLan();

System.out.println("姓名:" + huaHu.name + ",年龄:" + huaHu.age + ",性别:" + huaHu.sex); //其他人

huaHu.horseKillEnemy();

huaHu.suggest();//用她父亲的名字信息在向别人作自我介绍//huaHu.Prettify()//无法使用//战争结束了

HuaMuLan huaMuLan =(HuaMuLan)huaHu;//花木兰变回自己

System.out.println("姓名:" + huaMuLan.name + ",年龄:" + huaMuLan.age + ",性别:" +huaMuLan.sex);//自己特有函数

huaMuLan.Prettify();

System.out.println("幸福的过完了一生");

}

}

输出

姓名:花弧,年龄:60,性别:男

花木兰骑马杀敌

我叫花弧

姓名:花木兰,年龄:28,性别:女

花木兰涂脂抹粉

幸福的过完了一生

最后看个经典的多态例子

A类

public classA

{publicString show(D obj) {return ("A and D");

}publicString show(A obj) {return ("A and A");

}

}

B类

public class B extendsA

{publicString show(B obj){return ("B and B");

}publicString show(A obj){return ("B and A");

}

}

C类

public class C extendsB

{

}

D类

public class D extendsB

{

}

Main类

public classMain

{public static voidmain(String[] args) {

A a1= newA();

A a2= newB();

B b= newB();

C c= newC();

D d= newD();

System.out.println("1--" +a1.show(b));

System.out.println("2--" +a1.show(c));

System.out.println("3--" +a1.show(d));

System.out.println("4--" +a2.show(b));

System.out.println("5--" +a2.show(c));

System.out.println("6--" +a2.show(d));

System.out.println("7--" +b.show(b));

System.out.println("8--" +b.show(c));

System.out.println("9--" +b.show(d));

}

}

输出

1--A and A2--A and A3--A and D4--B and A5--B and A6--A and D7--B and B8--B and B9--A and D

你做对了吗?

======================================================

如果有什么不对或错误,欢迎指正,lz好及时修改,不至于误导别人,万分感谢!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值