Java类的设计----多态性及其应用
多态性及其应用
多态性
多态—在Java中,子类的对象可以替代父类的对象使用
一个变量只能有一种确定的数据类型
一个引用类型变量可能指向(引用)多种不同类型的对象
Person p = new Student();
Object o = new Person();//Object类型的变量o,指向Person类型的对象
o = new Student(); //Object类型的变量o,指向Student类型的对象
父类类型的变量可以指向子类的对象
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = new Student();
e.school = “pku”; //非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。
虚拟方法调用(Virtual Method Invocation)
正常的方法调用
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
虚拟方法调用(多态情况下)
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。—— 动态绑定
多态性应用举例
方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
public class Test {
public void method(Person e) {
//……
e.getInfo();
}
public static void main(Stirng args[]) {
Test t = new Test();
Student m = new Student();
t.method(m); //子类的对象m传送给父类类型的参数e
}
}
Person类
public class Person {
//仅在类的内部可以访问.
private String email;
//在同一个包内该属性可以被访问.
String major;
//在子类中该属性可以被访问, 且该子类可以跨包
protected int salary;
//访问权限最高, 无论是否在一个包内, 无论是否是子类都可以被访问.
public String name;
public int age;
public Date birth;
private String lover;
public Person(int i) {
System.out.println("[Person's constructor...]");
}
public Person() {
// TODO Auto-generated constructor stub
}
public String getInfo(){
return "name: " + name + ", " + "age: " + age + ", " + "birth: " + birth;
}
}
Man类继承Person类
public class Man extends Person{
public void work(){
System.out.println("男人工作...");
}
@Override
public String getInfo() {
return "Man's getInfo";
}
}
Woman类继承Person类
public class Woman extends Person{
public void shopping(){
System.out.println("女人购物...");
}
}
TestPerson类
public class TestPerson {
public static void main(String[] args) {
//多态
//1. 创建一个 Man 的实例
Man m1 = new Man();
//2. 创建一个 Woman 的实例
Woman w1 = new Woman();
//3. 创建一个 Person 的实例
Person p1 = new Person();
/**
* 多态: 在Java中,父类的引用可以指向子类的对象.
* 1. 在多态情况下, 父类的实例变量不能再访问子类中添加的属性和方法
* 2. 方法的调用是在运行时确定的,所以调用的是 Man 类的 getInfo() 方法。—— 动态绑定(虚拟方法法调用)
* 3. 在存在父子关系(多态)的情况下, 可以把父类的引用类型强制转换为子类的引用类型. 若实际上不能进行转换则系统
* 会抛出 java.lang.ClassCastException 异常.
* 4. 如何避免出现 java.lang.ClassCastException 异常呢? 在转换之前可以先判断一下对象实际上是否为指定的子类类型.
* 使用 instanceof 运算符. 注意, 使用 instanceof 运算符, 必须要求前面的引用指向的变量和后边的类之间存在父子关系
*/
//需要一个人, 但来的是一个男人! OK. 因为男人一定是一个人.
Person p2 = new Man();
System.out.println(p2.getInfo());
//需要一个人, 但来的是一个女人! OK. 因为女人一定是一个人
Person p3 = new Woman();
//在多态情况下, 可以进行强制的类型转换
Man m2 = (Man) p2;
System.out.println(p3 instanceof Man);
System.out.println(p3 instanceof Woman);
// System.out.println(m2 instanceof Person);
// Man m3 = (Man) p3;
//需要一个男人, 但来的是个人! NO. 因为人不一定是男人.
//Man m2 = new Person();
//需要个男人, 但来的是一个女人。 NO!
//Man m3 = new Woamn();
Student student = new Student();
student.name = "Jerry";
student.birth = new Date();
student.age = 1;
student.school = "atguigu";
System.out.println(student.getInfo());
}
}
instanceof 操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
public class Person extends Object {…}
public class Student extends Person {…}
public class Graduate extends Person {…}
public void method1(Person e) {
if (e instanceof Person)
// 处理Person类及其子类对象
if (e instanceof Student)
//处理Student类及其子类对象
if (e instanceof Graduate)
//处理Graduate类及其子类对象
}
练习
建立TestInstance 类,在类中定义方法method1(Person e); 在method1中:
(1)根据e的类型调用相应类的getInfo()方法。
(2)根据e的类型执行: 如果e为Person类的对象,输出:“a person”; 如果e为Student类的对象,输出 “a student” “a person ” 如果e为Graduate类的对象,输出: “a graduated student” “a student” “a person”
class Person {
protected String name="person";
protected int age=;
public String getInfo() {
return "Name: "+ name + "\n" +"age: "+ age;
}
}
class Student extends Person {
protected String school="pku";
public String getInfo() {
return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school;
}
}
class Graduate extends Student {
public String major="IT";
public String getInfo(){
return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school+"\nmajor:"+major;
}
}
对象类型转换 (Casting )
基本数据类型的Casting:
小的数据类型可以自动转换成大的数据类型
如long g=20; double d=12.0f
可以把大的数据类型强制转换(casting)成小的数据类型
如 floate f=(float)12.0 int a=(int)1200L
对Java对象的强制类型转换称为造型
从子类到父类的类型转换可以自动进行
从父类到子类的类型转换必须通过造型(强制类型转换)实现
无继承关系的引用类型间的转换是非法的
在造型前可以使用instanceof操作符测试一个对象的类型
对象类型转换举例
public class Test {
public void method(Person e) { //设Person类中没有getschool()方法
System.out.pritnln(e.getschool()); //非法,编译时错误
if(e instanceof Student) {
Student me = (Student)e; //将e强制转换为Student类型
System.out.pritnln(me.getschool());
}
}
public static void main(Stirng args[]) {
Test t = new Test();
Student m = new Student();
t.method(m);
}
}
Person类
public class Person {
protected String name="person";
protected int age=50;
public String getInfo() {
return "Name: "+ name + "\n" +"age: "+ age;
}
}
class Student extends Person {
protected String school="pku";
public String getInfo() {
return "Name: "+ name + "\nage: "+ age
+ "\nschool: "+ school;
}
}
class Graduate extends Student{
public String major="IT";
public String getInfo()
{
return "Name: "+ name + "\nage: "+ age
+ "\nschool: "+ school+"\nmajor:"+major;
}
}
TestInstance类
package com.atgugu.java.ex;
public class TestInstance {
/*
在类中定义方法method1(Person e);
在method1中:
(1)根据e的类型调用相应类的getInfo()方法。
(2)根据e的类型执行:
如果e为Person类的对象,输出:“a person”;
如果e为Student类的对象,输出
“a student”
“a person ”
如果e为Graduate类的对象,输出:
“a graduated student”
“a student”
“a person”
*/
public void method1(Person e) {
String info = e.getInfo();
System.out.println(info);
if(e instanceof Graduate){
System.out.println("a graduated student");
}
if(e instanceof Student){
System.out.println("a student");
}
if(e instanceof Person){
System.out.print("a person");
}
System.out.println("\n");
}
public static void main(String[] args) {
TestInstance ti = new TestInstance();
Person p1 = new Person();
ti.method1(p1);
Person p2 = new Student();
ti.method1(p2);
Person p3 = new Graduate();
ti.method1(p3);
}
}
Java类的设计----多态性及其应用的更多相关文章
- Java类的设计----Object 类
Object类 Object类是所有Java类的根父类如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类 public class Person { ... } 等价于: ...
- Java类的设计----关键字super
关键字super 在Java类中使用super来引用父类的成分 super可用于访问父类中定义的属性 super可用于调用父类中定义的成员方法 super可用于在子类构造方法中调用父类的构造方法 su ...
- Java类的设计----访问控制
访问控制 可以对Java类中定义的属性和方法进行访问控制----规定不同的保护等级: public.protected.default.private //仅在类的内部可以访问. private St ...
- Java类的设计----方法的重写、覆盖
方法的重写.覆盖 在子类中可以根据需要对从父类中继承来的方法进行改造—覆盖方法(方法的重置.重写),在程序执行时,子类的方法将覆盖父类的方法. 覆盖方法必须和被覆盖方法具有相同的方法名称.参数列表和返 ...
- java类的设计原则
1.内聚性 类应该描述一个单一的实体,所有的类操作应该在逻辑上相互配合,支持一个连贯性的目标.例如:学生和教职工属于不同的实体,应该定义两个类. 2.一致性 要遵循一定的设计风格和命名习惯.给类.方法 ...
- java类和对象的基础(笔记)
在Java类的设计中,有时希望一个类在任何时候只能有一个实例.这时可以将该类设计为单例模式(singleton).要将一个类设计为单例模式,需要把类的构造方法的访问修饰符声明为private,然后在类 ...
- Java 类的热替换 —— 概念、设计与实现
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp71 Java 类的热替换 -- 概念.设计与实现 构建基于 Java ...
- Java SE 之 数据库操作工具类(DBUtil)设计
JDBC创建数据库基本连接 //1.加载驱动程序 Class.forName(driveName); //2.获得数据库连接 Connection connection = DriverManager ...
- Java实验项目三——编程实现Person类,学生类的设计及其继承关系
Program: 编程实现Person类,学生类的设计及其继承关系 代码如下: 定义抽象类Person 1 /* 2 * Description:建立抽象类 3 * 4 * Written By:Ca ...
随机推荐
- 在Spark中通过Scala + Mongodb实现连接池
How to implement connection pool in spark https://github.com/YulinGUO/BigDataTips/blob/master/spark/ ...
- 多进程监控自动关机工具升级远程关闭多台server——C# works with PowerShell
之前给单位做过一个多进程监控的自动关机工具,详见那篇blog. 这次领导又加了需求,说要等进程监控结束后,不止需要关闭主控端server,还需要关闭其他servers.于是就用到了我上篇文章所介绍的知 ...
- kubernetes 阿里云安装(kubeadm方式)
注意:不能修改hostnamecurl -sSL http://aliacs-k8s.oss-cn-hangzhou.aliyuncs.com/installer/kubemgr-1.6.1.sh & ...
- Liunx下NFS服务器的搭建与配置
一.NFS简介 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NF ...
- ExtJs 通过分析源代码解决动态加载Controller的问题
通过分析源代码解决动态加载Controller的问题 最近在研究ExtJs(4.2.0)的MVC开发模式,具体Extjs的MVC如何使用这里不解释,具体参见ExtJs的官方文档.这里要解决的问题是如何 ...
- OpenWRT中的按键和灯的GPIO控制实现
基于BarrierBreaker版本,基于AR9331 AP121 Demo单板 来进行描述 1.灯 A.在mach-ap121.c中,定义了灯所对应的GPIO定义: #define AP121_GP ...
- Windows 2008 R2组策略之二——GPO初探
与前一篇博文发表已经相去月余了,实在是有些不好意思了.感谢51CTO的大编们将小文加了推荐,这使我更加觉得自己产出太少,难于回馈大家的厚爱. 今天将这个系列的第二篇奉献给大家,以伺视听. 在上篇小文中 ...
- Entity Framework应用:Loading Entities
Entity Framework允许控制对象之间的关系,在使用EF的过程中,很多时候我们会进行查询的操作,当我们进行查询的时候,哪些数据会被加载到内存中呢?所有的数据都需要吗?在一些场合可能有意义,例 ...
- 解决spring-boot-starter-logging与log4j冲突
由于公司在super-bom里配置了检查规则,build项目时遇到错误: [ERROR] [XXX Enforcer Rules] find DuplicateClasses Found in:org ...
- powerdesigner与mysql数据库的连接
(1).在桌面新建一个mysql.dpc文件,里面可以什么内容也没有. (2).打开powerdesigner,操作如下: (3).把mysql.dcp文件选中: (4).建立连接属性: (5).测试 ...