2020-10-25

多态性

多态性是面向对象中的第三大主要特征,多态性是在继承性的基础之上扩展出来的概念,也就是说可以实现父子类之间的互相转换。

  • 多态性的基本概念

在 Java之中对于多态性有两种实现的模式:

  • 方法的多态性;

|- 方法的重载:同一个方法名称可以根据传入的参数的类型或个数的不同实现不同功能的执行;

class Message {
	public void print() {
		System.out.println("www.mldn.cn");
	}
	public void print(String str) {
		System.out.println(str);
	}
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

|- 方法的覆写:同一个方法可能根据使用子类的不同有不同的实现;

class Message {
	public void print() {
		System.out.println("www.mldn.cn");
	}
}
class DataBaseMessage extends Message {
	public void print() {
		System.out.println("Oracle数据库连接信息……");
	}
}
class NetWordMessage extends Message {
	public void print() {
		System.out.println("网络连接信息……");
	}
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
  • 对象的多态性:父子实例之间的转换处理,它有两种模式:

|- 对象向上转型:父类 父类实例 = 子类实例、自动完成转换;

|- 对象向下转型:子类 子类实例 = (子类)父类实例、强制完成转换。

从实际的转型处理来讲,大部分情况下考虑最多的一定是对象的向上转型(90%)、对于对象的向下转型往往都在使用子类特殊功能(子类可以对父类进行功能扩充)的时候要采用向下转型(3%),还有一些时候是不会考虑转型的(String类、7%)。

  • 对象向上转型(接收或返回参数的统一性)

对象转型的处理属于多态性,而这一特性必须在继承性的基础上实现。

范例:观察一个简单代码

class Message {
	public void print() {
		System.out.println("www.mldn.cn");
	}
}
class DataBaseMessage extends Message {
	public void print() {
		System.out.println("Oracle数据库连接信息……");
	}
}
public class JavaDemo3 {

	public static void main(String[] args) {
		DataBaseMessage msg = new DataBaseMessage();
		msg.print();
	}
}

本程序是一个最简单的方法覆写操作实现,整体的程序之中可以发现,由于现在实例化的是子类对象,并且子类对象覆写了父类中的print()方法,所以调用的是被覆写过的方法。

范例:观察向上转型

public class JavaDemo3 {
	public static void main(String[] args) {
		Message msg = new DataBaseMessage();//向上转型
		msg.print();
	}
}
Oracle数据库连接信息……

那么这个时候就需要进行思考了,向上转型这种操作有什么主要的用处呢?

范例:向上转型

class Message {
	public void print() {
		System.out.println("www.mldn.cn");
	}
}
class DataBaseMessage extends Message {
	public void print() {
		System.out.println("Oracle数据库连接信息……");
	}
}
class WebServiceMessage extends Message {
	public void print() {
		System.out.println("web服务器连接信息……");
	}
}
public class JavaDemo3 {
	public static void main(String[] args) {
		fun(new DataBaseMessage());//Message msg = new DataBaseMessage();//向上转型
		fun(new WebServiceMessage());//Message msg = new WebServiceMessage();
	}
	public static void fun(Message msg) {//现在传递的是哪一个都可以接收
		msg.print();
	}
}
Oracle数据库连接信息……
web服务器连接信息……

向上转型的主要特点在于,可以对参数进行统一的设计,但是为什么此时不使用重载来解决当前问题呢?

class Message {
	public void print() {
		System.out.println("www.mldn.cn");
	}
}
class DataBaseMessage extends Message {
	public void print() {
		System.out.println("Oracle数据库连接信息……");
	}
}
class WebServiceMessage extends Message {
	public void print() {
		System.out.println("web服务器连接信息……");
	}
}
public class JavaDemo3 {
	public static void main(String[] args) {
		fun(new DataBaseMessage());//Message msg = new DataBaseMessage();//向上转型
		fun(new WebServiceMessage());//Message msg = new WebServiceMessage();
	}
	public static void fun(DataBaseMessage msg) {//现在传递的是哪一个
		msg.print();
	}
	public static void fun(WebServiceMessage msg) {//现在传递的是哪一个
		msg.print();
	}
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

现在的操作利用了重载解决了当前的设计,的确可以实现与之前完全一样的效果。但是在进行程序类设计的时候除了满足于当前的要求之外,还需要做出可维护性的设计,如果说现在随着项目的发展,Message产生了3W个子类,那么这个时候每当扩充一个Message子类之后就需要追加一个fun()的方法重载,这样就对程序的维护性造成很大影响。

  • 对象向下转型

向下转型主要特点在于需要使用到一些子类自己特殊的定义处理。

范例:实现向下转型

package edu.fjut.lyh36;
class People{
	public void print() {
		System.out.println("一个正常的人类行为,吃饭、睡觉、繁衍。");
	}
}
class SuperMan extends People{
	public String fly() {
		return "我可以飞。。。";
	}
	public String fire() {
		return "我可以喷火。。。";
	}
}

向上描述的是一些公共的特征,而向下描述的是子类自己特殊的定义环境,但是需要明确的是,向下转型并不是一件安全的事情。因为在进行向下转型之前一定要首先发生向上转型。

范例:错误案例

Exception in thread "main"java.lang.ClassCastException: Person cannot be cast to SuperMan at JavaDemo. main(JavaDemo. java: 20)

以后只要是发生对象的向下转型之前一定要首先发生向上转型,两个没有任何关系的实例如果要发生强制转换,那么就会出现“ClassCastException”异常,所以向下转型并不是一件安全的事情。

  • instanceof 关键字

通过分析可以发现向下转型本身是一件存在有安全隐患的操作,所以为了保证向下转型的正确性,往往需要在进行转型之前进行判断,判断某个实例是否是某个类的对象,这个就需要通过instanceof语法来实现,语法如下:

对象 instanceof类

该判断将返回一个boolean类型,如果是 true表示实例是指定类对象。

范例:观察instanceof的使用

public class JavaDemo4 {
	public static void main(String[] args) {
		People per = new People();//不转型
		System.out.println(per instanceof People);//true
		System.out.println(per instanceof SuperMan);//false
	}
}

范例:观察instanceof关键字

public class JavaDemo4 {
	public static void main(String[] args) {
		People per = new SuperMan();//向上转型
		System.out.println(per instanceof People);//true
		System.out.println(per instanceof SuperMan);//true
	}
}

所以在日后进行项目的开发过程之中,如果要执行对象的向下转型,最好先判断一次。

public class JavaDemo4 {
	public static void main(String[] args) {
		People per = new SuperMan();//向上转型
		if(per instanceof SuperMan) {
			SuperMan man = (SuperMan) per;
			System.out.println(man.fly());
			System.out.println(man.fire());
		}
	}
}

在以后进行一些完善性的程序开发的过程之中,对于转型之前一定要使用instanceof判断。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个 SQL 语句,用于向借阅表中插入数据。该表包含以下字段:借阅编号、读者编号、书籍编号、借阅日期、归还日期、借阅状态。每条数据表示一次借阅记录。其中借阅编号、读者编号、书籍编号、借阅日期和借阅状态是必填项,归还日期为可选项,如果借阅状态为“已还”则必须填写归还日期。 具体插入的数据如下: - 借阅编号:100001,读者编号:123413,书籍编号:0001,借阅日期:2020-11-05,归还日期:NULL,借阅状态:借阅 - 借阅编号:100002,读者编号:223411,书籍编号:0002,借阅日期:2020-9-28,归还日期:2020-10-13,借阅状态:已还 - 借阅编号:100003,读者编号:321123,书籍编号:1001,借阅日期:2020-7-01,归还日期:NULL,借阅状态:过期 - 借阅编号:100004,读者编号:321124,书籍编号:2001,借阅日期:2020-10-09,归还日期:2020-10-14,借阅状态:已还 - 借阅编号:100005,读者编号:321124,书籍编号:0001,借阅日期:2020-10-15,归还日期:NULL,借阅状态:借阅 - 借阅编号:100006,读者编号:223411,书籍编号:2001,借阅日期:2020-10-16,归还日期:NULL,借阅状态:借阅 - 借阅编号:100007,读者编号:411111,书籍编号:1002,借阅日期:2020-9-01,归还日期:2020-9-24,借阅状态:已还 - 借阅编号:100008,读者编号:411111,书籍编号:0001,借阅日期:2020-9-25,归还日期:NULL,借阅状态:借阅 - 借阅编号:100009,读者编号:411111,书籍编号:1001,借阅日期:2020-10-08,归还日期:NULL,借阅状态:借阅
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值