目录
向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
Animal animal = new Cat("大橘",2);
- public class Animal {
- String name;
- int age;
- public Animal(String name, int age){
- this.name = name;
- this.age = age;
- }
- public void eat(){
- System.out.println(name + "吃饭");
- }
- }
猫类
- public class Cat extends Animal{
- public Cat(String name,int age){
- super(name,age);//帮助父类构造
- }
- @Override
- public void eat (){
- System.out.println(name+"吃鱼");
- }
- public void mew(){
- System.out.println("喵喵喵");
- }
- }
狗类
- public class Dog extends Animal {
- public Dog(String name,int age){
- super(name,age);
- }
-
- @Override
- public void eat() {
- System.out.println(name+"吃骨头");
- }
- public void bark(){
- System.out.println("汪汪汪");
- }
- }
1. 直接赋值
- public class TestAnimal {
- public static void main(String[] args) {
- Animal cat = new Cat("大橘",2);//子类对象赋值给父类对象
- cat.eat();
- }
- }

此时父类Animal和子类Cat中都有eat方法,当创建的父类对象cat被子类赋值时,执行的是子类中的eat方法
2.方法传参
- public class TestAnimal {
- public static void eatFood(Animal animal){//形参为父类型引用,可以接收任意子类的对象
- animal.eat();
- }
- public static void main(String[] args) {
- Animal cat = new Cat("大橘",2);//子类对象赋值给父类对象
- Dog dog = new Dog("小黑",3);
- cat.eat();
- eatFood(cat);
- eatFood(dog);
- }
- }

3.方法返回
- public class TestAnimal {
- public static Animal reAinmal(String var){
- if("狗"==var){
- return new Dog("小狗",2);
- }else if("猫"==var){
- return new Cat("小猫",3);
- }else{
- return null;
- }
- }
- public static void eatFood(Animal animal){
- animal.eat();
- }
- public static void main(String[] args) {
- Animal cat = new Cat("大橘",2);//子类对象赋值给父类对象
- Dog dog = new Dog("小黑",3);
- cat.eat();
- eatFood(cat);
- eatFood(dog);
- Animal animal = reAinmal("狗");
- animal.eat();
- animal = reAinmal("猫");
- animal .eat();
- }
- }

注意:向上转型不能调用子类特有的方法。
将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类方法,但有时候可能需要子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。
- public class TestAnimal2 {
- public static void main(String[] args) {
- Cat cat = new Cat("大橘",2);
- Dog dog = new Dog("小黑", 1);
- Animal animal = cat;//向上转型
- animal.eat();
- animal = dog;
- animal.eat();
- animal.bark();
- // 编译失败,编译时编译器将animal当成Animal对象处理
- // 而Animal类中没有bark方法,因此编译失败
- cat = (Cat)animal;
- // 向下转型 // 程序可以通过编程,但运行时抛出异常---
- // 因为:animal实际指向的是狗 // 现在要强制还原为猫,无法正常还原,运行时抛出:ClassCastException
- cat.mew(); // animal本来指向的就是狗,因此将animal还原为狗也是安全的
- dog = (Dog)animal;
- dog.bark();
- }
- }


- public class TestAnimal2 {
- public static void main(String[] args) {
- Cat cat = new Cat("大橘",2);
- Dog dog = new Dog("小黑", 1); // 向上转型
- Animal animal = cat;
- animal.eat();
- animal = dog;
- animal.eat();
- if(animal instanceof Cat){
- cat = (Cat)animal;
- cat.mew();
- }
- if(animal instanceof Dog){
- dog = (Dog)animal;
- dog.bark();
- }
- }
- }

现在有如下代码:
- public class Shape {
- //属性....
- public void draw() {
- System.out.println("画图形!");
- }
- }
- class Rect extends Shape{
- @Override
- public void draw() {
- System.out.println("矩形");
- }
- }
- class Cycle extends Shape{
- @Override
- public void draw() {
- System.out.println("圆形");
- }
- }
- class Flower extends Shape{
- @Override
- public void draw() {
- System.out.println("花");
- }
- }
我们需要写一个函数来打印多个形状(矩形,圆,花)
- public static void drawShapes(){
- //创建一个shape对象的数组
- Shape[] shapes = new Shape[]{new Rect(),new Cycle(),new Flower()};
- for(Shape shape: shapes){
- shape.draw();
- }
- }
-
- public static void main(String[] args) {
- drawShapes();
- }

可扩展能力更强
- public class Shape {
- //属性....
- public void draw() {
- System.out.println("画图形!");
- }
- }
- class Rect extends Shape{
- @Override
- public void draw() {
- System.out.println("矩形");
- }
- }
- class Cycle extends Shape{
- @Override
- public void draw() {
- System.out.println("圆形");
- }
- }
- class Flower extends Shape{
- @Override
- public void draw() {
- System.out.println("花");
- }
- class Triangle extends Shape {
- @Override
- public void draw() {
- System.out.println("三角形");
- }
- }
- class B{
- public B(){
- func();
- }
- public void func(){
- System.out.println("B.func()");
- }
- }
- class D extends B{
- private int num = 1;
- public void func(){
- System.out.println("D.func()"+num);
- }
- }
- public class Test2 {
- public static void main(String[] args) {
- D d = new D();
- }
- }

正常来说应该输出的是B.func(),这里输出的确是D.func()0,注意这里的num不是1而是0,说明num还未被赋值。
说明当在父类当中调用方法时,如果该方法被子类重写,调用的是子类的方法。