override enter -c ont 处理 shopping exce int
多态性及其应用
多态—在 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 类
- 1 public class Woman extends Person {
- 2 3 public void shopping() {
- 4 System.out.println("女人购物...");
- 5
- }
- 6
- }
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());
- }
- }
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"
- 1 class Person {
- 2 protected String name = "person";
- 3 protected int age = 50;
- 4 public String getInfo() {
- 5
- return "Name: " + name + "\n" + "age: " + age;
- 6
- }
- 7
- }
- 8 class Student extends Person {
- 9 protected String school = "pku";
- 10 public String getInfo() {
- 11
- return "Name: " + name + "\nage: " + age + "\nschool: " + school;
- 13
- }
- 15
- }
- 16 class Graduate extends Student {
- 17 public String major = "IT";
- 18 public String getInfo() {
- 20
- return "Name: " + name + "\nage: " + age + "\nschool: " + school + "\nmajor:" + major;
- 22
- }
- 23
- }
基本数据类型的 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 类的设计 ---- 多态性及其应用
来源: http://www.bubuko.com/infodetail-2223971.html