Java面向对象(中篇)

不能调用子类所特有的方法、属性:编译时,p2是Person类型。(接上篇)

p2.name = "Tom";

有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明父类类型,导致编译时只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。

如何才能调用子类特有的属性和方法?

向下转型:使用强制类型转换符。

Man m1 = (Man)p2;

m1.earnMoney();

m1.isSmoking = true;

使用强转时,可能出现ClassCastException的异常。

Woman w1 = (Woman)p2;

w1.goShopping();

instanceof关键字的使用

a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。

使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。

if(p2 instanceof Woman){
    Woman w1 = (Woman)p2;
    w1.goShopping();
    System.out.println("********Woman**********");
}

if(p2 instanceof Man){
    Man m2 = (Man)p2;
    m2.earnMoney();
    System.out.println("*******Man*********")
}

如果a instanceof A返回true,则a instanceof B也返回true。

其中,类B是类A的父类。

if(p2 instanceof Person){
    System.out.println("********Person**********");
}

if(p2 instanceof Object){
    System.out.println("*******Object*********")
}

练习:

问题一:编译通过,运行时不通过

Person p3 = new Woman();
Man m3 = (Man)p3;

问题二:编译通过,运行也通过

Object obj = new Woman();
Person p = (Person)obj;

问题三:编译不过

Man m5 = new Woman();

 多态的练习:

1.若子类重写了父类方法,就意味着子类是定义的方法彻底覆了父类里的同名方法,系统将不可能把父类里的方法转移到子类中:编译看左边,运行看右边。

2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边。

import com.sun.xml.internal.stream.StaxErrorReporter;

class Base{
    int count = 10;

    public void display(){
        System.out.println(this.count);
    }
}

class Sub extends Base{
    int count = 20;

    public void display(){
        System.out.println(this.count);
    }
}

public class FieldMethodTest{
    public static void main(String[] args){
        Sub s = new Sub();
        System.out.println(s.count);
        s.display();
        Base b = s;
        System.out.println(b == s);
        System.out.println(b.count);
        b.display();
    }
}

 建立InstanceTest类,在类中定义方法method(Person e):

public class InstanceTest {
    public static void main(String[] args){
        InstanceTest test = new InstanceTest();
        test.method(new Student());
    }

    public void method(Person e){
        String info = e.getInfo();
        System.out.println(info);

        if(e instanceof Graduate){
            System.out.println("a graduated student");
            System.out.println("a student");
            System.out.println("a person");
        }else if (e instanceof Student){
            System.out.println("a student");
            System.out.println("a person");
        }else {
            System.out.println("a person");
        }
    }
}

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 "Nmae:" + 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;
    }
}

 定义一个测试类GeometricTset,编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术)。编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。

public class GeometricObject {
    protected String color;
    protected double weight;

    public String getColor() {
        return color;
    }

    public double getWeight() {
        return weight;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public GeometricObject(String color, double weight) {
        super();
        this.color = color;
        this.weight = weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double findArea(){
        return 0.0;
    }
}
import com.sun.org.apache.bcel.internal.generic.GETFIELD;

public class Circle extends GeometricObject {

    private double radius;

    public Circle(double radius, String color, double weight) {
        super(color, weight);
        this.radius = radius;

    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double findArea(){
        return Math.PI * radius * radius;
    }
}

import sun.dc.pr.PRError;

public class MyRectangle extends GeometricObject{
    private double width;
    private double height;

    public MyRectangle(double width,double height,String color, double weight) {
        super(color, weight);
        this.height = height;
        this.width = width;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public void setHeight(double height) {
        this.height = height;
    }
    @Override
    public double findArea(){
        return width * height;
    }
}
public class GeometricTest {
    public static void main(String[] args){
        GeometricTest test = new GeometricTest();

        Circle c1 = new Circle(2.3,"white",1.0);
        test.displayGeometricObject(c1);
        Circle c2 = new Circle(3.3,"white",1.0);
        test.displayGeometricObject(c2);

        boolean isEquals = test.equalsArea(c1,c2);
        System.out.println("c1和c2的面积是否相等:" + isEquals);

        MyRectangle rect = new MyRectangle(2.1,3.4,"rad",2.0);
        test.displayGeometricObject(rect);
    }
    public void displayGeometricObject(GeometricObject o){
        System.out.println("面积为:" + o.findArea());
    }
    public boolean equalsArea(GeometricObject o1,GeometricObject o2){
        return o1.findArea() == o2.findArea();
    }
}

总结:今天学习了向下转型的使用、instanceof关键字的使用、向下转型的几个常见问题、多态练习:调用方法和属性、多态性练习:基本操作、多态性练习:几何图形、多态性练习:重写方法。

明日计划:学习equals()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值