本文主要是介绍Java学习的第十五天(JavaSE精英篇05_多态),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、多态:同种事物不同的表现形式
实现多态的三个前提:1.要实现子父类继承关系(通过类实现一个接口),2.要有方法的重写,3.父类引用指向子类对象
package com.bianyiit.cast;public class Demo1 {//多态:实现的三个前提//1.要实现子父类继承关系(通过类实现一个接口)//2.要有方法的重写//3.父类引用指向子类对象public static void main(String[] args) {//new Animal().eat();Animal a1 = new Dog(); //new Dog-->子类对象 Animal a1-->父类引用a1.eat();}
}
//定义一个动物类
class Animal{//成员方法public void eat(){System.out.println("吃东西..");}
}
class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗啃泥..");}
}
二、多态中成员的特点(变量、方法和静态方法)
1.动态绑定:在运行的时候会指向具体的对象
2.编译期(没点击运行之前,如果出现红线表明编译时出错)和运行期(点击运行时,正常运行还是报错)
package com.bianyiit.cast;public class Demo2 {public static void main(String[] args) {//System.out.println(new Dog2().color);Animal2 a1 = new Dog2();System.out.println(a1.color);a1.eat();a1.sleep();}
}
class Animal2{//定义一个成员变量String color="白色";public void eat(){System.out.println("我是一只动物..");}public static void sleep(){System.out.println("动物正在睡觉..");}
}
class Dog2 extends Animal2{String color="黑色";@Overridepublic void eat() {System.out.println("狗啃泥..");}//@Overridepublic static void sleep() {System.out.println("狗正在睡觉..");}
}
1.成员变量:编译期,如果父类里面没有成员变量就会报错,如果子类里面没有成员变量没问题运行期,运行出来的结果显示的是父类的成员变量的值
2.成员方法:编译期,如果父类里面没有成员方法就会报错,如果子类里面没有成员方法没问题运行期,运行出来的结果显示的是子类的成员方法的内容
3.静态方法:编译期,如果父类里面没有静态方法就会报错,如果子类里面没有静态方法没问题运行期,运行出来的结果显示的是父类的静态方法的内容
总结:使用多态应用的时候,成员变量 成员方法 静态方法编译期看的都是父类(父类中有这个东西才能够使用)* 运行时只有成员方法看的是子类的具体对象(调用的是子类的方法----动态绑定)* 注意:多态有一个局限性:无法调用子类特有的成员
三、如果想去调用子类特有的成员该怎么办?
调用子类特有的成员:数据类型的转换:基本数据类型的转换自动转换 (由小转大)byte shor char-->int-->long-->float-->double boolean不参与任何数据的转换强制转换(由大转小---会损失精度)引用数据类型的转换:向上转型(小的转大的)向下转型(大的转小的)
package com.bianyiit.cast;public class Demo3 {public static void main(String[] args) {Animal3 a1 = new Dog3();//(向上转型---小的自动转大的) 狗自动转换成动物a1.eat();//动态绑定---调用的是子类的方法Dog3 d1=(Dog3)a1; //向下转型(大的转小的) 动物强制转换成狗d1.eat();d1.sleep();//转型之后调用(子类)狗里面的特有的成员方法}
}
class Animal3{public void eat(){System.out.println("动物");}
}
class Dog3 extends Animal3{@Overridepublic void eat() {System.out.println("狗");}public void sleep(){System.out.println("狗正在睡觉..");}
}
四、多态的优点
package com.bianyiit.cast;public class Demo4 {public static void main(String[] args) {/* 多态的优点:1.继承的优点也就是多态的优点(1.提高了代码的复用性 ) 2.提高程序的扩展性。*///以工厂生产手机为例Factory f1 = new Factory();f1.produce(new XiaoMiPhone());f1.produce(new RedNotePhone());}
}
//定义一个工厂用来生产手机
class Factory{public void produce(Phone p){p.run();}
}
class Phone{public void run(){}
}
class XiaoMiPhone extends Phone{@Overridepublic void run() {System.out.println("生产小米手机中..");}
}
class RedNotePhone extends Phone{@Overridepublic void run() {System.out.println("生产红米手机中..");}
}
五、内部类的使用
5.1 成员内部类
package com.bianyiit.cast;public class Demo7_ChengYuanNeiBuNei {public static void main(String[] args) {//创建外部类对象 直接通过外部类的对象调用外部类的成员方法(内部包含内部类的实例化成员)//new Out().run();new Out().new In().study(); //成员方法System.out.println(new Out().new In().num); //成员变量}
}
//定义一个外部类
class Out{//成员变量int num=10;//成员方法/*public void run(){System.out.println("--调用外部类的成员方法-->然后在该方法中调用内部类的成员");//创建内部类的第一种方式,在外部类的成员方法中创建内部类对象//new In().study();//System.out.println(new In().num);}*///成员内部类(与成员变量处于同一级别)class In{//内部类的成员变量int num=20;//内部类的成员方法public void study(){System.out.println("学习中..");}}
}
5.2 静态内部类
package com.bianyiit.cast;public class Demo8_JinTaiNeiBuNei {//静态内部类 静态内部类里面不能访问非静态成员public static void main(String[] args) {new Animal8.Dog8().sleep();System.out.println(new Animal8.Dog8().num);}
}
class Animal8{static int num=10;static class Dog8{int num=20;public void sleep(){System.out.println("狗正在睡觉..");}}
}
5.3 局部内部类
package com.bianyiit.cast;public class Demo9_JuBuNeiBuNei {public static void main(String[] args) {//因为局部内部类的作用范围只在外部类的成员方法里面,一旦出了这个范围就不能使用了//所以局部内部类的创建只能在外部类的成员方法里面去创建,并且只能在局部内部类的后面才能创建成功!new Out9().printout();}
}
class Out9{//成员变量int num=10;//成员方法public void printout(){System.out.println("这是一个外部类的方法");//局部变量int num=20;//如果在这里创建局部内部类对象,在此之前连类都没有定义出来,所以在编译时就报错了!!//new In9().printin();//局部内部类class In9{//局部内部类的成员变量int num=30;//局部内部类的成员方法public void printin(){System.out.println("这是一个局部内部类");}}//如果在这里创建局部内部类对象并调用方法,可以使用!new In9().printin();System.out.println(new In9().num);}
}
5.4 匿名内部类(这个在多线程中用的很多)
package com.bianyiit.cast;public class Demo10_NiMingNeiBuNei {public static void main(String[] args) {//匿名内部类:用来创建类/接口的子类对象用的Out10 o1= new Out10(){@Overridepublic void Out10() {System.out.println("我是一只猫");}};o1.Out10();//匿名对象+匿名内部类new Out10(){@Overridepublic void Out10() {System.out.println("我是一头有思想的牛");}}.Out10();//多态:父类引用指向子类对象,动态绑定,在运行的时候会指向子类对象,它的会自动调用子类重写的成员方法//这里输出的效果和使用匿名内部类的效果是一致的!Out10 o2=new In10();o2.Out10();/*为什么要使用匿名内部类,减少代码量匿名内部类和通过继承父类创建一个子类,然后调用子类重写的成员方法的效果是一致的*/}
}
class Out10{public void Out10(){System.out.println("我是一只动物!!");}
}
//这里通过new Out10().out10();来使用子类的方法
class In10 extends Out10{@Overridepublic void Out10() {System.out.println("我是一只哈巴狗!");}
}
六、权限修饰符的比较
package com.bianyiit.quanxian.public1;public class Demo {public static void main(String[] args) {printPublic();printDefault();printPrivate();printProtected();}public static void printPublic(){System.out.println("public方法");}static void printDefault(){System.out.println("default方法");}private static void printPrivate(){System.out.println("private方法");}protected static void printProtected(){System.out.println("protected方法");}
}
package com.bianyiit.quanxian.public1;public class Demo1 extends Demo{public static void main(String[] args) {Demo.printPublic();Demo.printDefault();Demo.printProtected();}
}
package com.bianyiit.quanxian.protect;import com.bianyiit.quanxian.public1.Demo;public class Demo2 extends Demo{//在不同的包中,只有继承父类之后才能使用protected修饰的方法,而不能使用default修饰的方法,这是protected和default最大的区别public static void main(String[] args) {Demo.printPublic();Demo.printProtected();}
}
七、多态总结
1.多态:父类的引用指向了子类对象Animal a=new Cat();2.1 多态的优点1.继承的优点也就是多态的优点2.提高程序的扩展性。
2.2 缺点:无法直接访问子类特有的成员。多态就是向上转型。如果想访问子类特有的成员?向下转型3 继承:优缺点3.1 优点:1.提高代码的复用性2.提高程序的可维护性3.2 缺点:类与类之间的关联更加的密切。(耦合性增强)4 如何解决高耦合? 使用接口4.1 封装的优点:1.提高代码的复用性2.提高代码的安全性。
课后作业
package com.bianyiit.zonghe;public class Demo_Phone {public static void main(String[] args) {Factory factory = new Factory();factory.prodece(new XiaoMiPhone());factory.prodece(new RedNotePhone());factory.prodece(new PupperNotePhone());/*factory.run(new XiaoMiPhone());factory.run(new RedNotePhone());factory.run(new PupperNotePhone());*/}
}
//工厂:生产手机
class Factory{/*public void run(XiaoMiPhone x){x.produceXiao();}public void run(RedNotePhone r){r.produceRed();}public void run(PupperNotePhone p){p.producePupper();}*/public void prodece(Phone p){p.run();}//Phone p=new XiaoMiPhone();//p.run();当使用多态创建对象时,当父类和子类使用的是同一个成员方法,那么对象调用的是子类的成员方法
}
abstract class Phone{public abstract void run();
}
//小米手机的生产方法
class XiaoMiPhone extends Phone{@Overridepublic void run() {System.out.println("正在生产小米手机...");}
}
//红米手机的生产方法
class RedNotePhone extends Phone{@Overridepublic void run() {System.out.println("正在生产红米手机...");}
}
//紫米手机的生产方法
class PupperNotePhone extends Phone{@Overridepublic void run() {System.out.println("正在生产紫米手机...");}
}
这篇关于Java学习的第十五天(JavaSE精英篇05_多态)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!