面向对象-------多态

news/2024/7/4 9:42:35 标签: java

多态性
多态性是面向对象技术中最灵活的特性,主要是增强项目的可扩展性,
提高代码的可维护性。
多态性依赖继承特性,可以把多态理解为继承性的扩展或者深入。
在这里把多态性分为两方面来进行介绍,对象类型的多态和对象方法
的多态。
为了方便后续的讲解,首先给出一个继承结构的示例。
//文件名:SuperClass.java
public class SuperClass{
public void test(){
System.out.println(“SuperClass”);
}
}
// 文件名:SubbClass1.java
public class SubbClass1 extends SuperClass{
public void test(){
System.out.println(“SubbClass1”);
}
}
// 文件名:SubbClass2.java
public class SubbClass2 extends SuperClass{
public void test(){
System.out.println(“SubbClass2”);
}
}
在该示例代码中,SubbClass1 和 SubbClass2 是 SuperClass 的子类,
并且在子类的内部都覆盖父类中的 test方法。由于这三个类中都书写构造方法,
则按照默认构造方法的约定,每个类中都会被自动添加一个默认的构造方法。


对象类型的多态
对象类型的多态是指声明对象的类型不是对象的真正类型,而对象的
真正类型由创建对象时调用的构造方法进行决定。例外,按照继承性的说明,子
类的对象也是父类类型的对象,可以进行直接赋值。
例如如下代码:
SuperClass sc = new SubbClass1();
这里声明了一个 SuperClass 类型的对象 sc,然后使用 SuperClass 的
子类 SubbClass1 的构造方法进行创建,因为子类类型的对象也是父类类型的对
象,所以创建出来的对象可以直接赋值给父类类型的对象 sc。除了对象的赋值
以外,另外一个更重要的知识是 sc 对象虽然使用 SuperClass 声明的类型,但是
内部存储的却是 SubbClass1 类型的对象。这个可以 Java 语言的中 instanceof
运算符进行判断。
instanceof 是一个运算符,其作用是判断一个对象是否是某个类类型
的对象,如果成立则表达式的值为 true,否则为 false。语法格式如下:
对象名 instanceof 类名
需要注意的是:这里的类名必须和声明对象时的类之间存储继承关系,
否则将出现语法错误。
测试类型的代码如下:
/**
* 测试对象类型的多态
*/
public class TestObjectType {
public static void main(String[] args) {
SuperClass sc = new SubbClass1();
boolean b = sc instanceof SuperClass;
boolean b1 = sc instanceof SubbClass1;
System.out.println(b);
System.out.println(b1);
}
}
该测试程序的输出结果是:
true
true
由程序运行结果可以看出,sc 既是 SuperClass 类型的对象,也是
SubbClass1 类型的对象,而 SubbClass1 的类型被隐藏起来了,这就是对象的多
态。其实 sc 对象不仅仅在类型上是 SubbClass1 类型的,其存储的内容也是
SubbClass1 的内容,具体参看后面介绍的对象方法的多态。
对象类型的多态有很多的用途,极大的方便了对象的存储和传递,使
代码很方便的进行扩展,对于已有代码不产生影响。下面介绍两个基本的使用。
1. 对象的存储
在存储一系列不同子类的对象时,可以使用父类的结构来进行声明,这样可以方
便数据的存储,例如需要存储多个 SubbClass1 和 SubbClass2 的对象时,则可以
声明一个 SuperClass 类型的数组进行存储,示例代码如下:
SuperClass sc[] = new SuperClass[3];
sc[0] = new SubbClass1();
sc[1] = new SubbClass2();
sc[2] = new SubbClass1();
则这里的数组 sc,可以存储各个类型子类的对象,而数组中每个元素的值都是
存储的对应子类的对象,而只是在名义上的类型(语法上的类型)是 SuperClass
类型的,这样将方便程序的控制,当增加新的子类类型时,已有的代码不需要进
行改造就可以自动适应新的子类的结构。
例如新增了一个 SuperClass 的子类 SubbClass3,则该数组的代码可以修改成如
下:
SuperClass sc[] = new SuperClass[3];
sc[0] = new SubbClass1();
sc[1] = new SubbClass2();
sc[2] = new SubbClass3();
其它的代码都需要进行修改,就可以适应新的结构,这是多态性最主要的用途。
2.对象的传递
在方法的传入参数传递,以及返回值处理方面都从对象类型的多态中受益。在向
方法中传入参数时,如果该方法需要处理各个子类的对象,则只需要书写一个接
受父类类型对象的方法即可。例如:
public void testObjectTypeMethod(SuperClass sc){}
则该在调用该方法时,可以传入 SuperClass 的对象,也可以传入其子类的对象,
如果传入的是子类的对象,则子类对象中的内容不会丢失。例如调用的示例代码
如下:
SuperClass sc = new SuperClass();
SubbClass1 sc1 = new SubbClass1();
SubbClass2 sc2 = new SubbClass2();
testObjectTypeMethod(sc);
testObjectTypeMethod(sc1);
testObjectTypeMethod(sc2);
这里说明的只是调用时的语法结构,这样的特性将使我们只需要书写一个方法,
就可以处理所有子类的对象,简化代码的书写,降低代码的重复,从而降低维护
的难度。
另外,方法的返回值也可以利用到该特性,例如如下方法:
public SuperClass testObjectTypeMethod2(){}
则在该方法的内部,既可以返回 SuperClass 类型的对象,也可以返回其子类的
对象,也能简化代码的书写,便于代码的阅读和维护。
关于对象类型的多态,就简单的说明这么多,具体在项目中如何进行
使用,还需要一定的技巧和方法。


对象方法的多态
对象方法的多态基于方法的覆盖,也就是该对象调用的方法具体是子
类的方法还是父类的方法,由创建对象时使用的构造方法决定,而不是由声明对
象时声明的类型决定。
示例代码如下:
/**
* 测试对象方法的多态
*/
public class TestObjectMethod {
public static void main(String[] args) {
SuperClass sc = new SuperClass();
SubbClass1 sc1 = new SubbClass1();
SubbClass2 sc2 = new SubbClass2();
SuperClass sc3 = new SubbClass1();
testObjectTypeMethod(sc);
testObjectTypeMethod(sc1);
testObjectTypeMethod(sc2);
testObjectTypeMethod(sc3);
}
public static void testObjectTypeMethod(SuperClass sc){
sc.test(); //调用被覆盖的方法
}
}
该代码的执行结果如下:
SuperClass
SubbClass1
SubbClass2
SubbClass1
则从代码的执行结果看,虽然 testObjectTypeMethod 方法接收的是
SuperClass 类型的对象,但是传入子类对象时,子类对象的内容没有丢失,所
以在调用 test 方法时,还是调用的对应对象中对应的 test 方法。
这样就在功能上实现了对象的传递,从而保留了对象的内容,极大的
方便了代码的扩展性。
但是,由于 Java 在执行程序时,在程序运行的过程中,需要判断对象
调用的具体是父类的方法还是子类的方法,所以程序的执行速度会稍微有所降
低。

转载于:https://www.cnblogs.com/bocai2010000/p/6747549.html


http://www.niftyadmin.cn/n/1791021.html

相关文章

CMOS Sensor的调试经验分享【转】

转自:https://blog.csdn.net/yapingmcu/article/details/37817727 转自:http://bbs.52rd.com/forum.php?modviewthread&tid276351 CMOS Sensor的调试经验分享     我这里要介绍的就是CMOS摄像头的一些调试经验。  首先,要认识CMO…

自定义枚举类,jdk1.5之前和Enum枚举

/*** author xianyu* version 1.0* date 2019/12/30 20:27* 自定义枚举类*/ public class Season {// 1. 自定义枚举类对象的属性不应该允许被修改,所有应该使用private final修饰private final String SEASONNAME;private final String SEASONDESC;// 2. 私有化类的…

大数据日志传输之Kafka实战教程

大数据日志传输之Kafka实战 本套课程围绕Kafka架构详细讲解kafka的核心 架构组件,broker,consumer,producer,以及日志的分段存储,稀疏索引,副本平衡,重分区, 数据同步,Kafka的核心组控制器和消费者控制器等机制. 全面讲解java 最新版的api ,指定分区消费,流控制,手动commit,异步…

常见的运行时异常

//******************以下是运行时异常***************************//ArithmeticExceptionTestpublic void test6(){int a 10;int b 0;System.out.println(a / b);}//InputMismatchExceptionTestpublic void test5(){Scanner scanner new Scanner(System.in);int score sca…

NoSuchMethodError: ... addOnCompleteCallback

问题描述: 使用ES 2.3.1和Spark streaming 2.1时,出现以上报错信息。 原因: addOnCompleteCallback方法在spark2.0中移除了 The addOnCompleteCallback method was removed from the TaskContext in Spark 2.0. Spark 2.0 is not binary comp…

PHP实现excel导出

2019独角兽企业重金招聘Python工程师标准>>> 1&#xff1a;前端代码 <div id‘export’>导出excel表单</div> // //导入excel文件 $("#export").on(click, function(){ $.ajax({ url:"importexcel.php&quo…

异常处理机制:两种方式

throws 异常类型 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;/*** author xianyu* version 1.0* date 2020/1/1 15:53*/ public class ExceptionTest2 {public static void main(String[] arg…

MapReduce之Reduce Join

一 介绍 Reduce Join其主要思想如下&#xff1a; 在map阶段&#xff0c;map函数同时读取两个文件File1和File2&#xff0c;为了区分两种来源的key/value数据对&#xff0c;对每条数据打一个标签&#xff08;tag&#xff09;&#xff0c; 比如&#xff1a;tag0表示来自文件File1…