【java】向上转型和向下转型

```java
//面向对象中的转型只会发生在有继承关系的子类和父类中(接口的实现也包括在这里)

//向上转型
// 属性:调用的变量只能是父类中 例如下面human的age  结果是为0  而不是10   原因:在处理Java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定。所以在向上转型的情况下,对象的方法可以“找到”子类,而对象的属性还是父类的属性。
// 方法:父类引用指向子类对象,将会丢失子类和父类中不一致的方法;如果是子类已经重写 调用的就是子类方法  如果没有重写 就使用父类的方法

//向下转型
//回归原始  集合 Collection

//如何才能去获取子类属性??
//setter  和 getter
class Animal {
    public void eat() {
        System.out.println("父类的 eating...");
    }

    public void run() {
        System.out.println("父类的 running...");
    }
}

class Bird extends Animal {
    @Override
    public void eat() {
        System.out.println("子类重写的父类的  eatting...");
    }

    public void fly() {
        System.out.println("子类新方法  flying...");
    }
}

class Bird2 extends Animal {
    @Override
    public void eat() {
        System.out.println("子类重写的父类的  eatting...");
    }

    public void fly() {
        System.out.println("子类新方法  flying...");
    }
}

class Human {
    //默认权限  private public default protected
    //https://blog.csdn.net/qq_31686787/article/details/52553974
    //https://www.runoob.com/java/java-modifier-types.html
    private String name = "Human";
    //default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
    int age = 0;

    public void sleep() {
        System.out.println("父类人类 sleep..");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Male extends Human {
    private String name = "Male";
    private String grade = "Male";
    int age = 10;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void sleep() {
        System.out.println("男人 sleep..");
    }

    public void work() {
        System.out.println("男人 work..");
    }
}

class Female extends Human {
    private String name = "Female";
    int age = 0;

    @Override
    public void sleep() {
        System.out.println("女人 sleep..");
    }
}


class Fruit {
    public void myName() {
        /* *
         关于java this.getClass();
         * Java的每个类都带有一个运行时类对象,该Class对象中保存了创建对象所需的所有信息。
            可以用.class返回此 Object 的运行时类Class对象,也可以用getClass()获得。
            获得此对象后可以利用此Class对象的一些反射特性进行操作,
            例如:
            this.getClass().newInstance(); //用缺省构造函数创建一个该类的对象
            this.getClass().getInterfaces(); //获得此类实现的接口信息
            this.getClass().getMethods();//获得此类实现的所有公有方法
            Class.forName(" ... JDBC driver class name....");
             Class类的静态方法forName, 向DiverManager注册这个JDBC driver类
         * */
        System.out.println("我是父类  水果..." + this.getClass());
    }
}

class Apple extends Fruit {
    @Override
    public void myName() {
        System.out.println("我是子类  苹果...");
    }

    public void myMore() {
        System.out.println("我是你的小呀小苹果~~~~~~");
    }
}


public class Sys {

    public static void main(String[] args) {
        //向上转型
        Animal b = new Bird();
        //子类的方法
        b.eat();
        // b虽指向子类对象,但此时子类作为向上的代价丢失和父类不同的fly()方法  因此编译报错
        // b.fly();
        //父类的方法
        b.run();


        //传入的参数是子类
        sleep(new Male());
        sleep(new Female());


        Human human = new Male();
        //调用的是子类的方法
        human.sleep();
        //调用的是父类的变量
        System.out.println(human.age);
        //调用的是子类的变量
        System.out.println(human.getName());


        //其实这里就很好理解了    向上转型以后再向下转型 这样就可以恢复自己原本的身份了
        //但是这里需要注意的是 一定要记得原对象实例  就好比是原本是子类 可以转来转去  但是父类就不能往下转了  虽然编译不会错  但是运行的时候会报错的
        Fruit a = new Apple();
        a.myName();

        //向下转型,编译和运行皆不会出错(正确的)
        Apple aa = (Apple) a;
        //向下转型时调用的是子类的
        aa.myName();
        aa.myMore();

        //不安全的---向下转型,编译无错但会运行会出错
        Fruit f = new Fruit();
        Apple aaa = (Apple) f;
        aaa.myName();
        aaa.myMore();
    }

    //方法的参数是父类  体现出面向对象的抽象思想  根据传入的实际对象  完成向上转型 这样就没有必要重载了  只因为不同的参数
    public static void sleep(Human h) {
        h.sleep();
    }
}
```

向上转型还是比较好理解的,当参数为父类对象的时候  其实第一反应就应该是子类丢失了自己独特的方法  虽然方法调用的时候 还是子类的 但是变量只能是父类的了

向下转型就看着很奇怪了,我为啥不一开始就直接是初始化自己的实例呢。其实在阅读collection的代码的时候 就会发现了  向下转型是很有用的。具体可以看https://blog.csdn.net/xyh269/article/details/52231944 这个文章,下面这个demo也是来自其。

```java
public interface Electronics {
}

public class Thinkpad implements Electronics {

    //Thinkpad引导方法
    public void boot() {
        System.out.println("welcome,I am Thinkpad");
    }

    //使用Thinkpad编程
    public void program() {
        System.out.println("using Thinkpad program");
    }

}

public class Keyboard implements Electronics {

    //使用键盘输入
    public void input() {
        System.out.println("using Keyboard input");
    }

}


public class Mouse implements Electronics {

    //鼠标移动
    public void move() {
        System.out.println("move the mouse");
    }

    //鼠标点击
    public void onClick() {
        System.out.println("a click of the mouse");
    }
}


public class Test {

    public static final int THINKPAD = 0;
    public static final int MOUSE = 1;
    public static final int KEYBOARD = 2;

    public static void main(String[] args) {

        //添加进购物车
        ShopCar shopcar = new ShopCar();
        shopcar.add(new Thinkpad());
        shopcar.add(new Mouse());
        shopcar.add(new Keyboard());

        //获取大小
        System.out.println("购物车存放的电子产品数量为 ——> " + shopcar.getSize());

        //开始测试thinkpad电脑
        Thinkpad thinkpad = (Thinkpad) shopcar.getListItem(THINKPAD);
        thinkpad.boot();
        thinkpad.program();

        System.out.println("-------------------");

        //开始测试Mouse鼠标
        Mouse mouse = (Mouse) shopcar.getListItem(MOUSE);
        mouse.move();
        mouse.onClick();

        System.out.println("-------------------");

        //开始测试Keyboard键盘
        Keyboard keyboard = (Keyboard) shopcar.getListItem(KEYBOARD);
        keyboard.input();
    }
}
```




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值