```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();
}
}
```
【java】向上转型和向下转型
最新推荐文章于 2022-08-24 13:53:33 发布