Java 多态的详解
来源:互联网 发布:newsql数据库哪个最好 编辑:程序博客网 时间:2024/06/01 07:16
1.什么是多态?
一个对象的多种状态
比如:
教师 a =老钟;
员工 b= 老钟;
2.多态体现
(1)Father类
非静态成员变量x
静态成员变量y
非静态方法eat,方法体输出父类信息
静态方法speak();方法体输出父类信息
(2):Son类
非静态成员变量x
静态成员变量y
非静态方法eat,方法体输出子类信息
静态方法speak();方法体输出子类信息
class Father {int x = 1;static int y = 2;void eat() {System.out.println("开吃");}static void speak() {System.out.println("小头爸爸");}}class Son extends Father {int x = 3;static int y = 4;void eat() {System.out.println("大头儿子很能吃");}static void speak() {System.out.println("大头儿子。");}}class Demo {public static void main(String[] args) {Father f = new Son(); // 父类引用指向了子类对象。System.out.println(f.x); System.out.println(f.y); f.eat(); f.speak(); }}
Son类继承父类
1:创建Father f=new Son();
这就是父类引用指向了子类对象。
想想下列问题:
问f.x=?(非静态) --1
问f.y=?(静态) --2
问f.eat()输出的是子类还是父类信息?(非静态)----子类
问f.speak()输出的是子类还是父类信息?(静态)----父类
运行效果如图:
那为什么会有这样的结果呢?看下面的总结~
3.总结:
(1)当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量
(2)当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量
所以:父类和子类有相同的成员变量,多态下访问的是父类的成员变量。
(3)当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法。
(4)当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法。
4.多态体现-总结:
(1)父类引用变量指向了子类的对象
(2)父类引用也可以接受自己的子类对象
5.多态前提:类与类之间有关系,继承或者实现
6.多态弊端提高扩展性,但是只能使用父类引用指向父类成员。
7.多态特点非静态
(1)编译时期,参考引用型变量所属的类是否有调用的方法,如果有编译通过。没有编译失败
(2)运行时期,参考对象所属类中是否有调用的方法。
(3)总之成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点,无论编译和运行参考左边(引用型变量所属的类)。
在多态中,静态成员函数特点,无论编译和运行都参考左边
8.多态的作用(1)多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。
/* 1:定义功能,根据输出任何图形的面积和周长。子类重写了父类的抽象方法,多态下,会执行子类的非静态方法。2:多态可以作为返回值类型。获取任意一辆车对象3:抽象类和接口都可以作为多态中的父类引用类型。*/abstract class MyShape{public abstract double getArea();public abstract double getLen();}class Rect extends MyShape{double width ;double height;Rect(){}Rect(double width ,double height){this.width=width;this.height=height;}public double getArea(){return width*height;}public double getLen(){return 2*(width+height);}}class Circle extends MyShape{ double r; public static final double PI=3.14; Circle(){ } Circle(double r){ this.r=r; }public double getLen(){ return 2*PI*r; }public double getArea(){ return PI*r*r; }}class Demo{public static void main(String[] args){System.out.println();print(new Rect(3,4)); //MyShape m =new Rect(3,4);print(new Circle(3)); } //根据用户传入的图形对象,计算出该图形的面积和周长 //1:多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。 public static void print(MyShape m){ System.out.println(m.getLen()); System.out.println(m.getArea()); } }效果图:
(2)多态可以作为返回值类型
/*获取任意一辆车对象 1:定义汽车类,有名字和颜色,提供有参和无参构造,有运行的行为。 2:定义Bmw类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。 3:定义Benz类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。 4:定义Bsj类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。 5:定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。 1:使用(int)Math.round(Math.random()*2); 生成0-2之间随机数。 Math 类 2:使用if else 判断,指定,0,1,2 new 不同汽车 并返回。 6:调用该方法,发现多态的好处。 */class Car {String name;String color;Car() {}Car(String name, String color) {this.name = name;this.color = color;}void run() {System.out.println("跑跑。。。。");}}class Bmw extends Car {Bmw() {}Bmw(String name, String color) {super(name, color);}void run() {System.out.println("宝马很拉风。。。。");}}class Benz extends Car {Benz() {}Benz(String name, String color) {super(name, color);}void run() {System.out.println("奔驰商务首选。。。。");}}class Bsj extends Car {Bsj() {}Bsj(String name, String color) {super(name, color);}void run() {System.out.println("泡妞首选。。。。");}}class Demo {public static void main(String[] args) {int x = 0;while (x < 100) {Car c = CarFactory();c.run();x++;}}// 定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。// 使用随机数,0.1.2 if 0 bsj 1 bmw 2 bcpublic static Car CarFactory() {int x = (int) Math.round(Math.random() * 2);if (0 == x) {return new Bmw("宝马x6", "红色");} else if (1 == x) {return new Benz("奔驰", "黑色");} else if (2 == x) {return new Bsj("保时捷", "棕色");} else {return new Benz("Smart", "红色");}}}效果图:
(3)抽象类和接口都可以作为多态中的父类引用类型。
看第一个作用的例子~
9.多态类型转换
如何在多态下,使用父类引用调用子类特有方法。
(1)基本类型转换:
自动:小->大
强制:大->小
(2)类类型转换
前提:继承,必须有关系
自动:子类转父类
强转:父类转子类
class Father {void method1() {System.out.println("这是父类1");}void method2() {System.out.println("这是父类2");}}class Son extends Father {void method1() {System.out.println("这是子类1");}void method3() {System.out.println("这是子类3");}}class Demo {public static void main(String[] args) {Father f = new Son();f.method1(); // 这是子类1f.method2(); // 这是父类2// f.method3(); //编译报错。// 多态弊端,只能使用父类引用指向父类成员。// 类类型转换Son s = (Son) f;s.method3();System.out.println();}}效果图:
好了,多态就写完了~
- Java的多态详解
- Java 多态的详解
- java多态详解
- Java 多态详解
- JAVA多态详解
- java多态详解
- java多态详解
- Java多态详解
- 【Java】Java的继承和多态详解
- 【Java】Java的继承和多态详解
- 【Java】Java的继承和多态详解
- Java学习笔记(33)-- Java 多态的详解
- Java 多态笔记详解
- java的运行机制详解
- java的运行机制详解
- Java Object的详解
- java的synchronized详解
- java反射的详解
- TCP/IP协议中的端口
- 用户(user)和用户组(group)管理
- org.msgpack.core.MessagePacker
- JAVA之NIO按行读写大文件,完美解决中文乱码问题
- LinkedHashMap类源码解析
- Java 多态的详解
- 面试常见的基础--二份查找--binaryFind
- TCP通信(一)——同步连接
- hdu 1753 大明A+B
- 第一篇博客的自我介绍
- Web---图片验证码生成教程详解-从简单到复杂-从本地到前后台
- CListCtrl的主要事件及鼠标响应函数
- Handler实现app启动动画
- Objective-C实现多继承