Java基础-面向对象第三大特性之多态(polymorphism)

                                      作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.多态概述

  多态是继封装,继承之后,面向对象的第三大特性,多态的前提是继承。

  从现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三即是学生也是人。即出现两种形态。Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。

  最终多态体现为父类引用变量可以指向子类对象。多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

二.多态调用的三种形式

  多态调用方法,方法必须运行子类的重写!

1>.多态的定义格式:就是父类的引用变量指向子类对象。

 父类类型  变量名 = new 子类类型();
变量名.方法名();

2>.普通类多态定义的格式

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Father{
public void show(){
System.out.println("父类的show方法!");
}
} class Son extends Father{
public void show(){
System.out.println("子类重写父类的show方法!");
}
} public class MyInterfaceDemo{
public static void main(String[] args){
//Java中,对象的多态性,调用公式:“父类类型或者接口类型 变量 = new 子类对象();”
Father f = new Son();
f.show();
}
} /*
以上代码执行结果如下:
子类重写父类的show方法!
*/

3>.抽象类多态定义的格式

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ abstract class Father{
public abstract void eat();
} class Son extends Father{
public void eat(){
System.out.println("儿子喜欢吃米饭!");
}
} public class MyInterfaceDemo{
public static void main(String[] args){
//抽象类Father,子类是Son
Father f = new Son();
f.eat();
}
} /*
以上代码执行结果如下:
儿子喜欢吃米饭!
*/

4>.接口多态定义格式

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ interface Father{
public abstract void smoking();
} class Son implements Father{
public void smoking(){
System.out.println("儿子会抽烟!");
}
} public class MyInterfaceDemo{
public static void main(String[] args){
//接口Father,实现类Son
Father f = new Son();
f.smoking();
}
} /*
以上代码执行结果如下:
儿子会抽烟!
*/

三.多态中成员变量的特点

1>.成员变量(编译运行全看父类)

  a>.编译的时候,参考父类中有没有这个变量,如果有,编译成功,没有则编译失败;

  b>.运行的时候,运行的是父类中的变量值;

2>.成员方法(编译看父类,运行看子类

  a>.编译的时候,参考父类中有没有这个方法,如果有,编译成功,没有则编译失败

  b>.运行的时候,运行的是子类的重写方法;

3>.静态成员方法

  没有多态性。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Father{
int age = 30;
public void show(){
System.out.println("Father的方法");
}
} class Son extends Father{
int age = 8;
public void show(){
System.out.println("Son的方法");
}
} public class MyInterfaceDemo{
public static void main(String[] args){
Father f = new Son();
System.out.println(f.age);
f.show();
}
} /*
以上代码执行结果如下:
30
Son的方法
*/

四.instanceof关键字

  我们了解多态之后,会发现一个对象的数据类型不一定会保持不变。当我们想要确定一个对象是否是某个类时,就会用到比较运算符,只不过它很特殊,不能赢大于小于或是等于号直接进行判断,而是要用到关键字,即instanceof,它只能用作比较引用数据类型,用来比较一个引用类型的变量,是不是这个类型的对象。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ abstract class Person{
public abstract void sleep();
} class Student extends Person{
public void sleep(){
System.out.println("学生在休息!");
}
} class Teacher extends Person{
public void sleep(){
System.out.println("老师在休息!");
}
} public class PersonDemo{
public static void main(String[] args){ Person p = new Student(); p = new Teacher(); boolean flag = p instanceof Student; System.out.println("引用数据类型'p'是否为Student类型:>>> " + flag); p.sleep();
}
} /*
以上代码执行结果如下:
引用数据类型'p'是否为Student类型:>>> false
老师在休息!
*/

五.多态转型

1>.多态的向上转型

  多态常见的就是自动类型提升,将取值范围小的,自动提升为取值范围大的。范围小的,看成是子类,范围大的看成父类。

优点:

  这样做的好出就是可以调用子类父类的公共属性(方法)。

缺点:

  无法调用子类特有的属性(方法)。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ abstract class Person{
public abstract void sleep();
} class Student extends Person{
public void sleep(){
System.out.println("学生在休息!");
}
} class Teacher extends Person{
public void sleep(){
System.out.println("老师在休息!");
}
} public class PersonDemo{
public static void main(String[] args){ //从子类对象往父类变量赋值(自动类型提升,向上转型)
Person p = new Student(); }
}

2>.多态的向下转型

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ abstract class Person{
public abstract void sleep();
} class Student extends Person{
public void sleep(){
System.out.println("学生在休息!");
}
} class Teacher extends Person{
public void sleep(){
System.out.println("老师在休息!");
}
} public class PersonDemo{
public static void main(String[] args){ //从子类对象往父类变量赋值(自动类型提升,向上转型)
Person p = new Student(); //从父类类型转向子类类型(向下转型)
Student s = (Student)p; }
}

3>.多态转型的案例

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ abstract class Animal{
public abstract void eat();
} class Cat extends Animal{
public void eat(){
System.out.println("猫吃猫粮!");
} public void catchMouse(){
System.out.println("猫抓老鼠!");
}
} class Dog extends Animal{
public void eat(){
System.out.println("狗吃狗粮!");
} public void run(){
System.out.println("狗能跑!");
}
} public class AnimalDemo{
public static void main(String[] args){
//两个子类,使用两次多态调用
Animal a1 = new Cat();
Animal a2 = new Dog();
//a1,a2调用子类父类共有方法,运行走子类的重写方法
a1.eat();
a2.eat();
/*类型向下转型,强制转换,调用子类的特有,防止发生异常,
a1属于CatUI小,转成Cat类,a2属于Dog对象,转成Dog类,我们
可以用关键字instanceof判断。
*/
if(a1 instanceof Cat){
Cat c = (Cat)a1;
c.catchMouse();
} if(a2 instanceof Dog){
Dog d = (Dog)a2;
d.run();
} }
} /*
以上代码执行结果如下:
猫吃猫粮!
狗吃狗粮!
猫抓老鼠!
狗能跑!
*/

六.匿名对象

1>.匿名对象的概念   

  匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Person{
public void eat(){
System.out.println("人是铁,饭是钢,一顿不吃饿得慌!");
}
} public class PersonDemo{
public static void main(String[] args){ //有名字的对象,引用类型变量,可以反复使用eat方法。
Person p = new Person();
p.eat(); //匿名对象,没有引用变量,只能使用一次,如果你再通过new调用eat方法的话实际上是又新生成了一个对象。
new Person().eat();
new Person().eat(); }
}

2>.匿名对象的特点

  a>.创建匿名对象直接使用,没有变量名;

  b>.匿名对象在没有指定其引用变量时,只能使用一次;

  c>.匿名对象可以作为方法接受的参数,方法返回值使用;

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Person{
public void eat(){
System.out.println("人是铁,饭是钢,一顿不吃饿得慌!");
}
}
public class PersonDemo{
public static void main(String[] args){
//有名字的对象,引用类型变量,可以反复使用eat方法。
Person p = new Person();
p.eat();
//匿名对象,没有引用变量,只能使用一次,如果你再通过new调用eat方法的话实际上是又新生成了一个对象。
new Person().eat();
new Person().eat();
method(p); //匿名方法当实参
method(new Person());
p = method();
method(p);
}
//方法的返回值是Person类型,方法的return语句,返回的是这个类的对象。就可以用匿名对象来实现。
public static Person method(){
return new Person();
}
//调用方法method,传递Person类型对象
public static void method(Person p){
p.eat();
}
} /*
以上代码执行结果如下:
人是铁,饭是钢,一顿不吃饿得慌!
人是铁,饭是钢,一顿不吃饿得慌!
人是铁,饭是钢,一顿不吃饿得慌!
人是铁,饭是钢,一顿不吃饿得慌!
人是铁,饭是钢,一顿不吃饿得慌!
人是铁,饭是钢,一顿不吃饿得慌!
*/

七.内部类

1>.内部类概念

  a>.什么是内部类

    将类写在其它类的内部,可以写在其它类的成员位置和局部位置,这时写在其它类内部的类成为内部类,其它类也称为外部类。

  b>.什么时候使用内部类

    在描述事物时,若一个事物内部还包含其它可能包含的事物,比如在描述汽车时,汽车中还包含这发动机,这时发动机就可以使用内部类来描述。

  c>.内部类分类

    内部类分为成员内部类和局部内部类。我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符,继承与实现关系等。在内部类中可以直接访问外部类的所有成员。

2>.成员内部类的调用格式

  内部类可以使用外部类成员,包括私有变量。外部类要使用内部类的成员,必须建立内部类对象。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Outer{
private int a = 100;
class Inner{
public void inner(){
System.out.println("内部类方法inter " + a);
}
}
} public class InnerClassDemo{
public static void main(String[] args){
//创建内部类对象in
Outer.Inner in = new Outer().new Inner();
//调用内部类方法
in.inner();
}
} /*
以上代码执行结果如下:
内部类方法inter 100
*/

3>.成员内部类的同名变量调用

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Outer{
int a = 100;
class Inner{
int a = 200;
public void inner(){
int a = 300;
System.out.println("内部类局部变量(内部类成员方法)访问:>>> "+ a);
System.out.println("内部类成员变量访问:>>> "+ this.a);
System.out.println("外部类成员变量访问:>>> "+ Outer.this.a);
}
}
} public class InnerClassDemo{
public static void main(String[] args){
//创建内部类对象in
Outer.Inner in = new Outer().new Inner();
//调用内部类方法
in.inner();
}
} /*
以上代码执行结果如下:
内部类局部变量(内部类成员方法)访问:>>> 300
内部类成员变量访问:>>> 200
外部类成员变量访问:>>> 100
*/

3>.局部内部类

  局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可通过调用方法进行访问。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ class Outer{
public void out(){
class Inner{
public void inner(){
System.out.println("局部内部类方法!");
}
}
//创建我们定义的Inner对象
Inner in = new Inner();
//调用创建好的对象的方法,这样不管谁只要能调用out方法就会触发调用Inner类中的inner()方法啦!
in.inner();
}
} public class InnerClassDemo{
public static void main(String[] args){
new Outer().out();
}
} /*
以上代码执行结果如下:
局部内部类方法!
*/

4>.匿名内部类

  a>.匿名内部类概念

    内部类是为了应对更为复杂的类间关系。查看源代码中会涉及到,而在日常业务中很难遇到,这里不做赘述。最长用到的内部类就是匿名内部类,它是局部内部类的一种。定义的匿名内部类有两个含义:第一,临时定义某一指定类型的子类;第二,定义后即刻创建刚刚定义的这个子类的对象。

  b>.定义匿名内部类的作用与格式

    匿名内部类是创建某个子类对象的快捷方式。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ interface Smoking{
public abstract void smoking();
} public class SmokingDemo{
public static void main(String[] args){
//这就是用匿名对象实现接口并调用接口中的方法,切记不要忘记调用smoking()了哟!
new Smoking(){
public void smoking(){
System.out.println("运维不喜欢吸烟!");
}
}.smoking();
}
} /*
以上代码执行结果如下:
运维不喜欢吸烟!
*/

Java基础-面向对象第三大特性之多态(polymorphism )的更多相关文章

  1. Java基础—面向对象的三大特性

    面向对象有三大特性分别是继承.封装和多态. (1)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类 ...

  2. Java学习笔记二十五:Java面向对象的三大特性之多态

    Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...

  3. java中面向对象的三大特性小结

    java中面向对象的三大特性:封装.继承.多态 封装 把抽象的数据和对数据的操作封装在一起,隐藏变量的实现细节.数据被保护在内部,程序的其他部分只有通过被授权的操作(成员方法)才能对数据进行访问. 1 ...

  4. 3.java面向对象编程三大特性之多态

    面向对象编程的三大特性:封装.继承.多态 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对类的外部而言它的内部实现细节是隐藏的,暴露给外界的只是它的实现方法. ...

  5. 九、Java基础---------面向对象封装、继承、多态

    封装 1.1 基本概念  封装(encapsulation)是面向对象三大特征之一,它是指将对象的状态信心隐藏在对象的内部,不允许外部直接进行访问,而是通过该类提供的方法来实现对内部信息的操作和访问. ...

  6. python基础学习 Day19 面向对象的三大特性之多态、封装 property的用法(1)

    一.课前内容回顾 继承作用:提高代码的重用性(要继承父类的子类都实现相同的方法:抽象类.接口) 继承解释:当你开始编写两个类的时候,出现了重复的代码,通过继承来简化代码,把重复的代码放在父类中. 单继 ...

  7. python基础学习 Day19 面向对象的三大特性之多态、封装

    一.课前内容回顾 继承作用:提高代码的重用性(要继承父类的子类都实现相同的方法:抽象类.接口) 继承解释:当你开始编写两个类的时候,出现了重复的代码,通过继承来简化代码,把重复的代码放在父类中. 单继 ...

  8. Java面向对象的三大特性之一 多态

    多态: 子类重写父类方法 1)位置:子类和父类中有同名的方法 2)方法名相同,返回类型和修饰符相同,参数列表相同       方法体不同 多态的优势和应用场合 多态:同一个引用类型,使用不同的实例而执 ...

  9. python面向对象的三大特性之一多态

    多态 多态的特性是调用不同的子类将会产生不同的行为,而无需明确知道这个子类实际上是什么 说白了就是,不同的对象调用相同的方法,产生不同的行为 例如:s1是字符串类型,w1是列表,两个完全不同的对象,他 ...

随机推荐

  1. spring冲刺第十天

    调试运行,对整体的游戏方面进行改进.冲刺完了,但依然有很多问题,比如无法暂停,游戏结束后只能退出重来等

  2. 增加ubuntu的内存——设置Swap增加内存

    1.查看一下当前Swap分区的状态: $cat /proc/meminfo SwapTotal: 0 kB SwapFree: 0 kB 如果上面二项目都为0,说明没有Swap分区:如果不为0,则说明 ...

  3. vs2010调试-尝试调试dll源码。

    第一步: 打开“调试”——“选项和设置”——点击调试下“常规”——设置启用“启用.NET Framework源代码单步执行 ” 第二步 选择“符号”——选择Microsoft符号服务器——设置符号缓存 ...

  4. JQuery TextArea的取值与赋值问题---(textarea中回车清空问题)——个人转载整理

    JQuery TextArea的取值与赋值问题---(textarea中回车清空问题) JQuery TextArea的取值与赋值问题 首先,说明这不是一个简单的问题! 先说取值: $("# ...

  5. 微服务注册与发现 —— eureka

    基础概念 在微服务系统中,服务的注册和发现是第一步,常用的有: Eureka:https://github.com/Netflix/eureka Zookeeper:https://zookeeper ...

  6. Ubuntu16.04 下虚拟环境的创建与使用

    1. 虚拟环境   虚拟环境(virtual environment),顾名思义是虚拟出来的环境,通俗来讲,可以借助虚拟机,docker来理解虚拟环境,就是把一部分内容独立出来,我们把这部分独立出来的 ...

  7. Mac 下搭建 Apache 服务器

    Apache作为最流行的Web服务器端软件之一,它的优点与地位不言而喻.下面介绍下在Mac下搭建Apache服务器的步骤: (1)“前往” –>”个人” (2)在你的个人目录下新建一个文件夹,改 ...

  8. form表单转化json对象

    利用 $.fn 可以让每一个jquery 对象都能直接使用这个方法. //form表单转化json对象$.fn.serializeObject = function () { var o = {}; ...

  9. vm的三种网络模式

    Vm网卡的模式:网络地址转换模式(nat),仅主机(host-only),桥接模式(Brideged) VMware 的几个虚拟设备: ■ VMnet0:这是 VMware 用于虚拟桥接网络下的虚拟交 ...

  10. java杂项

    简单介绍==和equals区别==是判断两个变量或实例是不是指向同一个内存空间equals是判断两个变量或实例所指向的内存空间的值是不是相同 final, finally, finalize的区别fi ...