本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多态的相关问题,多态是面向对象程序设计的一个重要特征,指向同一个实体同时具有多种形式,指的是对象的多种形态,下面一起来看一下,希望对大家有帮助。
推荐学习:《java视频教程》
1. 概念多态是面向对象程序设计(oop)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
比如,你的女盆友让你买点水果回来,不管买回来的是苹果还是西瓜,只要是水果就行,这个就是生活中多态的体现
再比如,小猫、小狗、小猪我们可以把他们都归纳成小动物,每种小动物都需要吃东西,所以我们可以统一设置他们都必须吃,但是每种小动物的习性不一样,那这个就可以设置成小动物自己特有的功能,多态对象只能调用父类中定义子类中重写的功能,并不能调用子类的特有功能,这样就实现了代码的统一
2 . 特点多态的前提1:是继承多态的前提2:要有方法的重写父类引用指向子类对象,如:animal a = new cat();多态中,编译看左边,运行看右边
3. 练习:多态入门案例创建包: cn.tedu.oop
创建类: testdemo.java
package cn.tedu.oop2;/*本类用作多态的入门案例*/public class testdemo { public static void main(string[] args) { //6.创建“纯纯的”对象用于测试 animal a = new animal(); cat c = new cat(); dog d = new dog(); a.eat();//小动物animal吃啥都行~调用的是父类自己的功能 c.eat();//小猫爱吃小鱼干~调用的是子类重写后的功能 d.eat();//小狗爱吃肉骨头~调用的是子类重写后的功能 /*2.父类对象不可以使用子类的特有功能*/ //a.jump();//报错,animal类里并没有这个方法 //a.run();//报错,animal类里并没有这个方法 c.jump();//小猫cat跳的老高啦~,子类可以调用自己的功能 d.run();//小狗dog跑的老快啦~,子类可以调用自己的功能 //7.创建多态对象进行测试 /*3.口诀1:父类引用指向子类对象 * 解释:创建出来的子类对象的地址值,交给父类类型的引用类型变量来保存*/ animal a2 = new cat();//cat类对象的地址值交给父类型变量a2来保存 animal a3 = new dog();//dog类对象的地址值交给父类型变量a3来保存 //8.测试多态对象 /*4.口诀2:编译看左边,运行看右边 * 解释:必须要在父类定义这个方法,才能通过编译,把多态对象看作是父类类型 * 必须要在子类重写这个方法,才能满足多态,实际干活的是子类*/ a2.eat();//小猫爱吃小鱼干~,多态对象使用的是父类的定义,子类的方法体 }}/*1.多态的前提:继承+重写*///1.创建父类class animal{ //3.创建父类的普通方法 public void eat(){ system.out.println(小动物animal吃啥都行~); }}//2.1创建子类1class cat extends animal{ //4.1添加重写的方法 public void eat(){ system.out.println(小猫爱吃小鱼干~); } //5.1添加子类的特有功能 public void jump(){ system.out.println(小猫cat跳的老高啦~); }}//2.2创建子类2class dog extends animal{ //4.2添加重写的方法 @override public void eat(){ system.out.println(小狗爱吃肉骨头~); } //5.2添加子类的特有功能 public void run(){ system.out.println(小狗dog跑的老快啦~); }}
4. 多态的好处多态可以让我们不用关心某个对象到底具体是什么类型,就可以使用该对象的某些方法提高了程序的可扩展性和可维护性5. 多态的使用前提:多态对象把自己看做是父类类型
成员变量: 使用的是父类的成员方法: 由于存在重写现象,所以使用的是子类的静态成员: 随着类的加载而加载,谁调用就返回谁的6. 练习:多态成员使用测试创建包: cn.tedu.oop
创建类: testdemo2.java
package cn.tedu.oop2;/*本类用于测试多态成员的使用情况*/public class testdemo2 { public static void main(string[] args) { //7.创建纯纯的子类对象 dog2 d = new dog2(); system.out.println(d.sum);//20,子类自己的属性 d.eat();//小狗爱吃肉包子,子类自己的方法 //8.创建多态对象 /*口诀1:父类引用指向子类对象*/ /*口诀2:编译(保存)看左边,运行(效果)看右边*/ animal2 a = new dog2(); /*多态中,成员变量使用的是父类的*/ system.out.println(a.sum);//10 /*多态中,方法的声明使用的是父类的,方法体使用的是子类的*/ a.eat();//小狗爱吃肉包子 /*多态中,调用的静态方法是父类的,因为多态对象把自己看作是父类类型 * 直接使用父类中的静态资源*/ a.play();//没有提示,玩啥都行~ animal2.play(); }}//1.创建父类class animal2{ //3.创建父类的成员变量 int sum = 10; //4.创建父类的普通方法 public void eat(){ system.out.println(吃啥都行~); } //9.1定义父类的静态方法play public static void play(){ system.out.println(玩啥都行~); }}//2.创建子类class dog2 extends animal2{ //5.定义子类的成员变量 int sum = 20; //6.重写父类的方法 @override public void eat(){ system.out.println(小狗爱吃肉包子); } //9.2创建子类的静态方法play //@override /*这不是一个重写的方法,只是恰巧在两个类中出现了一模一样的两个静态方法 * 静态方法属于类资源,只有一份,不存在重写的现象 * 在哪个类里定义,就作为哪个类的资源使用*/ public static void play(){ system.out.println(小狗喜欢玩皮球~); }}
7 拓展7.1 设计汽车综合案例创建包: cn.tedu.oopexec
创建类: designcar.java
package cn.tedu.oop2;/*本类用于完成汽车设计案例*/public class designcar { public static void main(string[] args) { //9.创建一个纯纯的父类对象进行测试 car c = new car(); system.out.println(c.getcolor());//null c.start(); c.stop(); //c.swim();//报错,父类对象不可以调用子类的特有功能 //10.创建纯纯的子类对象做测试 bmw b = new bmw(); system.out.println(b.color);//五彩斑斓的黑 system.out.println(b.getcolor());//null b.start();//都让开,我的车要起飞啦~ b.stop();//唉呀妈呀熄火了~ //11.创建多态对象进行测试 car c2 = new tsl(); //system.out.println(c2.color); system.out.println(c2.getcolor()); c2.stop(); c2.start(); //c2.swim(); }}//1.通过分析,抽象形成一个汽车类class car{ //2.定义并封装汽车类的属性--成员变量 private string brand;//品牌 private string color;//颜色 private int id;//编号 private double price;//价格 //3.定义功能 public void start(){ system.out.println(我的小车车启动啦~); } public void stop(){ system.out.println(唉呀妈呀熄火了~); } public string getbrand() { return brand; } public void setbrand(string brand) { this.brand = brand; } public string getcolor() { return color; } public void setcolor(string color) { this.color = color; } public int getid() { return id; } public void setid(int id) { this.id = id; } public double getprice() { return price; } public void setprice(double price) { this.price = price; }}//4.创建子类class bmw extends car{ string color = 五彩斑斓的黑; //5.重写父类的方法 @override public void start(){ system.out.println(都让开,我的车要起飞啦~); }}//6.创建子类2class tsl extends car{ //7.重写父类的方法 @override public void stop(){ system.out.println(唉呀妈,怎么停不下来呢); } //8.添加子类的特有功能 public void swim(){ system.out.println(没想到吧,我还是个潜水艇); }}
7.2 多态为了统一调用标准package cn.tedu.oop2;public class testfruit { public static void main(string[] args) { fruit f = new fruit(); apple a = new apple(); orange o = new orange(); get(f); get(a); get(o); } //只需要创建一个方法,就可以执行截然不同的效果 //忽略子类对象的差异统一看作父类类型 public static void get(fruit f){ f.clean(); }}class fruit{ public void clean(){ system.out.println(水果要洗洗再吃); }}class apple extends fruit{ @override public void clean(){ system.out.println(苹果需要削皮); }}class orange extends fruit{ @override public void clean(){ system.out.println(橙子需要剥皮); }}
7.3 静态变量和实例变量的区别在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
7.4 向上转型和向下转型在java中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。
那么在这个过程中就存在着多态的应用。存在着两种转型方式,分别是:向上转型和向下转型。
向上转型:可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
比如:父类parent,子类child
父类的引用指向子类对象:parent p=new child();
说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类中声明过的方法,方法体执行的就是子类重过后的功能。但是此时对象是把自己看做是父类类型的,所以其他资源使用的还是父类型的。
比如:花木兰替父从军,大家都把花木兰看做她爸,但是实际从军的是花木兰,而且,花木兰只能做她爸能做的事,在军营里是不可以化妆的。
向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。这个是之前向上造型过的子类对象仍然想执行子类的特有功能,所以需要重新恢复成子类对象
parent p = new child();//向上转型,此时,p是parent类型
child c = (child)p;//此时,把parent类型的p转成小类型child
其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。
比如:花木兰打仗结束,就不需要再看做是她爸了,就可以”对镜贴花黄”了
推荐学习:《java视频教程》
以上就是一文掌握java 面向对象之多态的详细内容。