1:什么是多态

一个对象的多种状态

(老师)(员工)(儿子)

教师 a =老钟;

员工 b =老钟;

2:多态体现

  父类引用变量指向了子类的对象          Father f = new Son();

父类引用也可以接受自己的子类对象

1:Father类

1:非静态成员变量x

2:静态成员变量y

3:非静态方法eat,方法体输出父类信息

4:静态方法speak();方法体输出父类信息

class Father {
int x = 1;
static int y = 2; void eat() {
System.out.println("开吃");
} static void speak() {
System.out.println("小头爸爸");
}
}

2:Son类

1:非静态成员变量x

2:静态成员变量y

3:非静态方法eat,方法体输出子类信息

4:静态方法speak();方法体输出子类信息

class Son extends Father {
int x = 3;
static int y = 4; void eat() {
System.out.println("大头儿子很能吃");
} static void speak() {
System.out.println("大头儿子。");
}
}
class Demo1 {

	public static void main(String[] args) {

		Father f = new Son(); // 父类引用指向了子类对象。
System.out.println(f.x); // 1
System.out.println(f.y); // 2
f.eat(); // 输出的是子类的。
f.speak(); // 输出的是父类 }
}

  3总结:

  1:当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量

  2:当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量

   所以:父类和子类有相同的成员变量,多态下访问的是父类的成员变量。

  3:当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类的成员方法

  4:当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法

多态前提

1:类与类之间有关系,继承或者实现

多态弊端

1:提高扩展性,但是只能使用父类引用指向父类成员。

多态特点

非静态

     1:编译时期,参考引用型变量所属的类是否有调用的方法,如果有编译通过。没有编译失败

   2:运行时期,参考对象所属类中是否有调用的方法。

      3:总之成员函数在多态调用时,编译看左边,运行看右边。

      在多态中,成员变量的特点,无论编译和运行  参考左边(引用型变量所属的类)。

        在多态中,静态成员函数特点,无论编译和运行都参考左边

多态练习

  1:多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。

1:定义功能,根据输出任何图形的面积和周长。

abstract class MyShape{
public abstract double getArea();
public abstract double getLen();
}

2:定义Rect类继承MyShape

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);
}
}

3:定义Cricle类继承MyShape

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;
}
}

4:定义静态方法计算任意图形的面积和周长

1:未知内容参与运算,不能确定用户传入何种图形,使用多态。

1:形参定义为 MyShape my

2:调用计算面积方法,和计算周长方法。并打印

2:使用多态特性,子类重写了父类非静态方法,会执行子类的方法。

class Demo2{
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:定义汽车类,有名字和颜色,提供有参和无参构造,有运行的行为。

class Car {
String name;
String color;
Car() {
}
Car(String name, String color) {
this.name = name;
this.color = color;
}
void run() {
System.out.println("跑跑。。。。");
}
}

    2:定义Bmw类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。

class Bmw extends Car {
Bmw() {
}
Bmw(String name, String color) {
super(name, color);
}
void run() {
System.out.println("宝马很拉风。。。。");
}
}

    3:定义Benz类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。

class Benz extends Car {
Benz() {
}
Benz(String name, String color) {
super(name, color);
}
void run() {
System.out.println("奔驰商务首选。。。。");
}
}

    4:定义Bsj类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。

class Bsj extends Car {
Bsj() {
}
Bsj(String name, String color) {
super(name, color);
}
void run() {
System.out.println("泡妞首选。。。。");
}
}

5:定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。

1:使用(int)Math.round(Math.random()*2); 生成0-2之间随机数。

2:使用if else 判断,指定,0,1,2 new 不同汽车 并返回。

class Demo3 {
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 bc
public 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:抽象类和接口都可以作为多态中的父类引用类型。 多态之类型转型

1:案例定义Father类

1:定义method1和method2方法

class Father {
void method1() {
System.out.println("这是父类1");
}
void method2() {
System.out.println("这是父类2");
}
}

2:定义Son类继承Father类

1:定义method1(重写父类method1)和method2方法

class Son extends Father {
void method1() {
System.out.println("这是子类1");
}
void method3() {
System.out.println("这是子类3");
}
}

3:创建Father f=new Son();

1: f.method1() 调用的子类或者父类?

2: f.method2() 编译和运行是否通过?

3: f.method3() 编译和运行是否通过?(编译报错)

class Demo4 {
public static void main(String[] args) {
Father f = new Son();
f.method1(); // 这是子类1
f.method2(); // 这是父类2
// f.method3(); //编译报错。
// 多态弊端,只能使用父类引用指向父类成员。
// 类类型转换
Son s = (Son) f;
s.method3();
System.out.println();
}
}

4:如何在多态下,使用父类引用调用子类特有方法。

1:基本类型转换:

1:自动:小->大

2:强制:大->小

2:类类型转换

前提:继承,必须有关系

1:自动:子类转父类

2:强转:父类转子类

3:类型转换

1:Son s=(Son)f

2:s.method3();

案例:

1:定义Animal类颜色成员变量,无参构造,有参构造,run方法

class Animal {
String color;
Animal() {
}
Animal(String color) {
this.color = color;
}
void run() {
System.out.println("跑跑");
}
}

  2:定义Dog类,继承Animal,定义无参构造,有参构造(使用super调用父类有参构造),Dog的特有方法ProtectHome

class Dog extends Animal {
Dog() {
}
Dog(String color) {
super(color);
}
void run() {
System.out.println("狗儿跑跑");
}
void protectHome() {
System.out.println("旺旺,看家");
}
}

  3:定义Fish类,继承Animal,定义无参构造,有参构造(使用super调用父类有参构造),Fish特有方法swim

class Fish extends Animal {
Fish() {
}
Fish(String color) {
super(color);
}
void run() {
System.out.println("鱼儿水中游");
}
void swim() {
System.out.println("鱼儿游泳");
}
}

4:使用多态,Animal a=new Dog();

5:调用Dog的特有方法,ProtectHome

1:类类型转换,Dog d=(Dog)a;

2:d.protectHome

class Demo5 {

	public static void main(String[] args) {

		Animal ani = new Dog();
// ani.protectHome();
// 正常转换
Dog d = (Dog) ani;
d.protectHome(); // 多态例外
Animal an = new Animal();
// ClassCastException
// Dog d=(Dog)an // 多态例外
Animal dog = new Dog();
// ClassCastException
// Fish f = (Fish) dog; }
}

6:非多态

    1:Animal a=new Animal();

2:类类型转换

Dog d=(Dog)a;

d.protectHome();

3:编译通过,运行出现异常

1:ClassCastException

7:多态例外

1:Animal  a=new Dog();

2:类类型转换

1:Fish f=(Fish)a;

2:f.fish();

3:编译通过,运行异常

1:ClassCastException

4:虽然是多态,但是狗不能转为鱼,他们之间没有关系。

案例2  

1:定义一功能,接收用户传入动物,根据用于传入的具体动物,执行该动物特有的方法

2:使用多态,方法形参,不能确定用户传入的是那种动物

3:使用instanceof 关键字,判断具体是何种动物,

4:类转换,执行该动物的特有方法。

class Animal {
String color;
Animal() {
}
Animal(String color) {
this.color = color;
}
void run() {
System.out.println("跑跑");
}
}
class Dog extends Animal {
Dog() {
}
Dog(String color) {
super(color);
}
void run() {
System.out.println("狗儿跑跑");
}
void protectHome() {
System.out.println("旺旺,看家");
}
}
class Fish extends Animal {
Fish() {
}
Fish(String color) {
super(color);
}
void run() {
System.out.println("鱼儿水中游");
}
void swim() {
System.out.println("鱼儿游泳");
}
}
class Bird extends Animal {
Bird() {
}
Bird(String color) {
super(color);
}
void run() {
System.out.println("鸟儿空中飞");
}
void fly() {
System.out.println("我是一只小小鸟。。。。");
}
}
class Demo6 {
public static void main(String[] args) {
System.out.println();
doSomething(new Dog());
doSomething(new Bird());
doSomething(new Fish());
}
// 定义一功能,接收用户传入动物,根据用于传入的具体动物,执行该动物特有的方法
public static void doSomething(Animal a) {
if (a instanceof Dog) {
Dog d = (Dog) a;
d.protectHome();
} else if (a instanceof Fish) {
Fish f = (Fish) a;
f.swim();
} else if (a instanceof Bird) {
Bird b = (Bird) a;
b.fly();
} else {
System.out.println("over");
}
}
}

Java 多态透析 详细理解的更多相关文章

  1. Java ssh 框架 hibernate 详细理解

    Hibernate框架技术相信对大多数的 java 程序员并不陌生,数据表之间的关系如何通过Hibernate来建立,需要我们认真的分析数据表中数据项之间的交互: 数据库表的之间的关系有: (1)一对 ...

  2. Java设计模式透析之 —— 策略(Strategy)

    今天你的leader兴致冲冲地找到你,希望你能够帮他一个小忙.他如今急着要去开会.要帮什么忙呢?你非常好奇. 他对你说.当前你们项目的数据库中有一张用户信息表.里面存放了非常用户的数据.如今须要完毕一 ...

  3. Java设计模式透析之 —— 模板方法(Template Method)

    今天你还是像往常一样来上班,一如既往地開始了你的编程工作. 项目经理告诉你,今天想在server端添加一个新功能.希望写一个方法.能对Book对象进行处理.将Book对象的全部字段以XML格式进行包装 ...

  4. Java设计模式透析之 —— 组合(Composite)

    听说你们公司最近新推出了一款电子书阅读应用,市场反应很不错,应用里还有图书商城,用户可以在其中随意选购自己喜欢的书籍.你们公司也是对此项目高度重视,加大了投入力度,决定给此应用再增加点功能. 好吧,你 ...

  5. Java设计模式透析之 —— 单例(Singleton)

    写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...

  6. Java设计模式透析之 —— 适配器(Adapter)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400141 今天一大早,你的leader就匆匆忙忙跑过来找到你:“快,快,紧急任务 ...

  7. Java经验杂谈(2.对Java多态的理解)

    多态是面向对象的重要特性之一,我试着用最简单的方式解释Java多态: 要正确理解多态,我们需要明确如下概念:・定义类型和实际类型・重载和重写・编译和运行 其中实际类型为new关键字后面的类型. 重载发 ...

  8. Ruby设计模式透析之 —— 适配器(Adapter)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400153 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  9. Ruby设计模式透析之 —— 组合(Composite)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

随机推荐

  1. zabbix监控Elasticsearch集群

    本节以 zabbix 为例,介绍如何使用监控系统完成 Elasticsearch 的监控报警. github 上有好几个版本的 ESZabbix 仓库,都源自 Elastic 公司员工 unterge ...

  2. Sampling Distributions and Central Limit Theorem in R(转)

    The Central Limit Theorem (CLT), and the concept of the sampling distribution, are critical for unde ...

  3. kafka 0.10.2 消息生产者(producer)

    package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.*; import org.apache.kafk ...

  4. js的event事件

    一 .  焦点:使浏览器能够区分区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 我们可以通过一些方式给元素设置焦点 1.点击 2.tab   3.js 不是所有元素都能够接受 ...

  5. Scrapy中使用Django的Model访问数据库

    Scrapy中使用Django的Model进行数据库访问 当已存在Django项目的时候,直接引入Django的Model来使用比较简单 # 使用以下语句添加Django项目的目录到path impo ...

  6. Asp.Net Core-----简介与安装

    Asp.Net Core简介 ASP.NET Core 是一个全新的开源.跨平台框架,可以用它来构建基于网络连接的现代云应用程序,比如:Web 应用,IoT(Internet Of Things,物联 ...

  7. DOUAudioStreamer 中kqueue的应用

    DOUAudioStreamer是一个基于Core Audio的流式音频播放器,其中的DOUAudioEventLoop通过kqueue来控制音频的各种状态. kqueue简介(详情请看官方manua ...

  8. MACOS关闭指定端口

    因为用IDEA写项目的时候,有的时候结束Jetty导致端口没有释放,所以会出现占用的情况. MacOS结束端口占用进程的命令,和Linux的一样.先执行如下命令: lsof -i:8080 会有类似下 ...

  9. Thinkphp 3.0-3.1版代码执行漏洞

    近日360库带计划中播报的ThinkPHP扩展类库的漏洞已经查明原因:系官方扩展模式中的Lite精简模式中存在可能的漏洞(原先核心更新安全的时候 并没有更新模式扩展部分,现已更新).对于使用标准模式或 ...

  10. 软件测试基础(软件测试分类和工具组)firebug、firepath的安装

    白盒测试:需要了解内部结构和代码 黑盒测试:不关心内部结构和代码 灰盒测试:介于白盒黑盒之间 静态测试:测试时不执行被测试软件 动态测试:测试时执行被测试软件 单元测试:测试软件的单元模块 集成测试: ...