科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道一直不太明白的一个关于继承方面的问题

一直不太明白的一个关于继承方面的问题

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

一直不太明白的一个关于继承方面的问题

作者:csdn 来源:csdn 2009年12月17日

关键字: 问答 JavaSE java

  • 评论
  • 分享微博
  • 分享邮件

一直不太明白的一个关于继承方面的问题

例如:  Dog 类 继承了 Animal类。
  Animal dog = new Dog(); 和 Dog dog = new Dog();
  这两种声明dog对象有什么区别?

这要是放在项目中就可以看出好处了,书上的例子不美!
继承就是可以用父类的引用来new一个子类的对象
这种用法是为了产生多态
当调用父类中的方法时,如果子类有覆盖这个方法的话,那么调用的就是子类的这个方法。

这要是放在项目中就可以看出好处了,书上的例子不美!继承就是可以用父类的引用来new一个子类的对象 这种用法是为了产生多态, 当调用父类中的方法时,如果子类有覆盖这个方法的话,那么调用的就是子类的这个方法。
 

子类继承后可以重写,也可以不重写,看需要决定。如果重写的话在实例中调用的是新写的方法. 如果不重写的话在实例中调用的是父类的方法。

 

在内存分配上没有区别,都是Dog对象,但是第一种写法Animal dog = new Dog(); dog只能调用父类Animal里的方法和属性,要想使用子类Dog里的有父类Animal里没有的方法就比须向下转型,也就是强制转换(Dog)dog一下。
第二种写法Dog dog = new Dog(); 就没有这个问题了。

 

狗继承了动物!
动物 = new 狗;
这里只能调用动物的属性方法,如果狗继承动物后重写了动物里的一些方法,那么就调用狗重写的那个方法.
但是不能调用狗的自己的方法,比如狗欺负猫这个方法,动物没有,只有狗有.
狗 = new 狗;
可以调用狗从动物继承过来的方法,还包括它自己的特性的方法

 

1.内存分配
  Animal dog = new Dog(); 在堆区建立Dog对象,在栈区建立Animal引用,该引用指向Dog对象
  Dog dog = new Dog(); 在堆区建立Dog对象,在栈区建立Dog引用,该引用指向Dog对象
2.使用 
  Animal dog = new Dog();可以使用未被重写的非privateAnimal方法,Animal上非private所有属性,以及在Dog中重写Animal的方法 
  Dog dog = new Dog(); 可以使用Dog ,Animal的非 private属性和方法

 

java中对象类型的变量可以指向自己的实例或它的任何子类的实例
Animal dog = new Dog(); // 父类的引用指向子类的事例,dog变量的类型是父类的,可以把Dog看成是Animal
他们的区别就不难理解 Animal的引用可以指向其他子类,而这样就可以用到JAVA的动态帮定,
把父类的引用作为参数可以自动识别子类的方法,这样就不必要去写每个子类的具体逻辑
Java code
public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog("dog");
        System.out.println(getAnimalInfo(animal));
        animal = new Cat("Cat");
        System.out.println(getAnimalInfo(animal));
    }
   
    public static String getAnimalInfo(Animal animal) {
        return "This is " + animal.getName();
    }
}

abstract class  Animal {
    public abstract String getName();
}

class Dog extends Animal{
   
    private String name = "";
   
    public Dog(String name) {
        this.name = name;
    }
   
    public String getName() {
        return this.name;
    }
}

class Cat extends Animal {
    private String name = "";
   
    public Cat(String name) {
        this.name = name;
    }
   
    public String getName() {
        return this.name;
    }
}

如果不用多态,那每个子类都要写自己的逻辑,但子类很多很复杂的时候,多态的优点就体现出来了

 

运行时多态的三原则
1.对象不变;(改变的是主观认识)
2.对于对象的调用只能限于编译时类型的方法,如调用运行时类型方法报错。
在上面的例子中:Animal a=new Dog();对象a的编译时类型为Animal,运行时类型为dog。
注意:编译时类型一定要为运行时类型的父类或者同类型。
对于语句:Dog d=(Dog)a。将d强制声明为a类型,此时d为Dog(),此时d就可以调用运行时类型。注意:a和d指向同一对象。
3.动态类型判定实际调用的方法。即它调用覆盖后的方法。

 

多态的作用就是提取共性,加入我的程序中n多个子类继承了某个父类,而使用过程中我并不想知道我的一个方法调用属于那个子类的,只想把它当父类一样用,省去细节,这个时候多态的作用就体现了。就好像我们搞饲养要弄清楚各种鸡的品种,而搞屠宰并不在乎这些细节,只要是鸡就宰就行了。
 
 
因为有了继承,才有了子类和父类的定义。
从继承的语义上讲,是子类继承父类,所以子类拥有父类的非private变量和方法。
有了继承,也就出现多态性。从而有了Animal dog = new Dog(); ,这是多态的重要表现。
这是一种常用的写法,这种代码更灵活,如果哪天不想使用Dog中的方法,可以在编写一个类,
继承Animal,来替换Dog的操作。
 
 
(1)Animal dog=new Dog();
(2)Dog dog=new Dog();
第一个定义对象实现了多态,(1)和(2)中的调用方法其实是一样的,但是多态比较灵活
 
 
(1)Animal dog=new Dog();
(2)Dog dog=new Dog();
第一个定义对象实现了多态,(1)和(2)中的调用方法其实是一样的,但是多态比较灵活
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章