亲宝软件园·资讯

展开

龙生九子-浅谈Java的继承

Mikejiawei 人气:1
# 龙生九子-浅谈Java的继承 ![Java](https://img2020.cnblogs.com/blog/1525915/202003/1525915-20200321131458795-1281066724.jpg) 书接上回,我们之前谈过了类和对象的概念,今天我来讲一讲[面向对象程序设计](https://zh.wikipedia.org/wiki/面向对象程序设计)的另外一个基本概念—**继承** --- ## 目录 > + 为什么需要继承 > + 自动转型与强制转型 > + 继承能干啥 > + 复写和隐藏 > + super关键字 > + 多态的概念 ## 为什么需要继承 我们先先念一遍定义:利用继承,人们可以基于已存在的类构造一个新类。继承已存在的类就是复用(继承)这些类的方法和属性。在此基础上,还可以添加一些新的方法和属性,以满足新的需求。这是Java程序设计中的一项核心技术。 举个简单例子。俗话说 `龙生九子,各有所好` ,我们把 龙王 当成**父类**,他有九个儿子,相当于九个**子类**。每个子类都**继承**了父辈的真龙血脉(欧拉!),但是他们各有不同,擅长做不同的事情,相当于子类实现了**新的方法和属性**,以满足不同的需求。而且需要注意的是九子只有一个**爸爸**,也就是一个子类只能继承**一个父类**,不允许认多个爸爸(龙王:逆子!)。 举一个更贴近生活的例子。我们有一个Employee类来表示公司的员工,这个公司中经理的待遇与普通雇员的待遇存在这一些差异。不过,他们之间也存在这很多相同的地方例如,他们都领薪水。只是普通的员工在完成本质工作后仅领取薪水,而经理在完成了预期的业绩之后还能得到奖金。这种情况就需要使用继承。这是因为需要为经理定义一个新类Manager,以便增加一些新功能。但可以**重用**Employee类中已经编写的部分代码。 码来! ```java //创建一个Manager类继承employee类 //关键字:extends(继承) public class Manager extends Employee { private double bonus; ...//此处省略 public void setBonus(double bonus) { this.bonus = bonus; } } ``` 关键字extends表明正在构造的新类派生于一个已存在的类。我们可以看到,我们新建了一个 Manager类,他继承了 Employee类。那么,我们称 `Employee`为**父类**,`Manager`为**子类**。 ## 自动转型和强制转型 > 父慈子孝 ```java public class Animal { public static void testClassMethod() { System.out.println("The static method in Animal"); } public void testInstanceMethod() { System.out.println("The instance method in Animal"); } } public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public void eatMouse(){ System.out.println("I am a cat,so I can eat rats!"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; //这是自动转型 Cat anotherCat = (Cat)myCat; //这是强制转型 //myAnimal.testClassMethod(); //myAnimal.testInstanceMethod(); } } ``` 先看代码,我们新建了两个类: 父类`Animal`和子类 `Cat`。我没看到在 `public static void main(String[] args)`中,我们创建了一个Cat类的实例 myCat 。 接下来,我们把这个 `myCat`赋值给了 `Animal` 类型的实例 `myAnimal`。 这一步是什么意思呢? 我们可以这样想,一只猫一定是一只动物,所以把一个猫对象 赋给 一个动物对象是合情合理的。非常自然,我们称之为 **自动转型**。 但是值得注意的是当我们把 Cat 转型为 Animal 后,他就不能再调用子类特有的方法了,比如吃老鼠方法`eatMouse()`,因为你不能说任何一只动物都可以吃老鼠吧。我们没有在父类中实现这个吃老鼠方法,所以就不能调用。 再往下看`Cat anotherCat = (Cat)myCat;`,我们又把myCat 转型为 Cat型实例。但是我们在 myCat之前要加一个 `(Cat)` 这就是**强制转型**。但是要**注意**,在**强制转型**之前,一定要有 **自动转型**。因为你不能随便把一只动物就变成一只猫吧。编译器会自动进行运行时检查这个对象是否真的是 Cat类型 对象。 ## 继承能干啥 > 来来来,继承的好处都有啥,谁答对了就给他(笑) 我们先简单的预览一下: + 子类可以直接使用父类的属性和方法。 + 你可以声明一个和父类同名的属性,因此父类被**隐藏**(不推荐这样做)。 + 你可以新增父类没有的属性和方法。 + 你可以写和父类具有相同`签名`的实例方法,这称为 **复写**。 + 你可以写和父类具有相同`签名`的静态方法,这称为 **隐藏**。 + 你可以创建子类独有的新方法。 + 你可以使用 `super`关键字,在子类的构造方法中调用父类的构造方法。 接下来的我们将重点介绍 隐藏,复写,super的概念。 > **Definition:** Two of the components of a method declaration comprise the *method signature*—the method's name and the parameter types. > > 补充说明:方法的 `签名` 由,方法名和参数类型构成。 > > ```java > calculateAnswer(double, int, double, double) > ``` ### 复写和隐藏 接下来我们介绍一下,复写和隐藏的概念。 码来: ```java public class Animal { public static void testClassMethod() { System.out.println("The static method in Animal"); } public void testInstanceMethod() { System.out.println("The instance method in Animal"); } } public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); myCat.testClassMethod(); Animal myAnimal = myCat; myAnimal.testClassMethod(); myAnimal.testInstanceMethod(); } } ``` 我们新建了两个类,其中 `Animal`为父类,`Cat`为子类。他们分别实现了,一个静态方法`testClassMethod()`,一个实例方法 `testInstanceMethod()`。 在 `public static void main(String[] args)` 中我们先创建了一个 Cat 实例`myCat`,再调用了他的静态方法,再把`myCat` 自动转型为 `Animal`的实例 `myAnimal`。再分别调用它的静态方法和实例方法。 结果如下: ![结果](https://img2020.cnblogs.com/blog/1525915/202003/1525915-20200321131527700-2123571259.png) 第一行,我们用 myCat调用了静态方法,所以打印出了`The static method in Cat` , 我们把 myCat 自动转型后再次调用静态方法,结果发现,他调用的是父类的静态方法。 我们称此为隐藏,调用的结果取决于他是**子类**还是**父类**,当子类调用静态方法时,父类的静态方法**被隐藏**。 我们看到最后一行,明明我们是用父类的实例调用的 `testInstanceMethod()`,结果打印的是Cat,为什么呢?原因是父类的实例方法**被复写了**。只要他是子类的实例,调用实例方法只会得到子类的**复写方法**。 + 总结 | | 父类的实力方法 | 父类的静态方法 | | -------------- | ------------------------------ | ------------------------------ | | 子类的实例方法 | Overrides(复写) | Generates a compile-time error | | 子类的静态方法 | Generates a compile-time error | Hides(隐藏) | 我相信有同学会问:那有没有什么法子调用父类的实例方法呢?答:有,那就是 `super`关键字! ### super关键字 废话少说,看代码: ```java public class Superclass { String name = "parent"; public Superclass(String name){ this.name = name; } public void printMethod() { System.out.println("Printed in Superclass."); } } public class Subclass extends Superclass { String name = "son"; String id = "unique"; public Subclass(String name,String id){ super(name); //这里我们调用了父类的构造方法 this.id = id; } // overrides printMethod in Superclass public void printMethod() { super.printMethod(); //这里我们调用了父类的 printMethod方法! System.out.println("Printed in Subclass."); System.out.println("My name is: "+name+". My id is: "+id); } public static void main(String[] args) { Subclass s = new Subclass("son","1234"); s.printMethod(); } } ``` 我们得到如下结果: ```java Printed in Superclass. Printed in Subclass. My name is: son. My id is: 1234 ``` 我们可以看到,我们使用了 `super`关键字来调用 父类的 `printMethod`方法。 那么 super还能干吗呢,我们还可以用super来调用 父类的构造方法。 我们看到这行代码: ```java public Subclass(String name,String id){ super(name); this.id = id; } ``` 其中的 ` super(name);` 就调用了父类的构造方法,复用了代码,减少冗余代码。十分方便! > **注意**:如果我们没有在第一行写 super语句,编译器会自动调用父类的 **无参构造方法**! > > 如果你的父类没写无参构造方法,编译器会报错! ## 多态 字典中的多态性的定义是指生物学中的一种原理,其中生物或物种可以具有许多不同的形式或阶段。 该原理也可以应用于面向对象的编程和Java语言之类的语言。 一个类的子类可以定义自己的独特行为,但也可以共享父类的某些相同功能。 ```java class Animal { public void talk(){ System.out.println("I am Animal!"); } } class Cat extends Animal { public void talk() { System.out.println("I am Cat!"); } } class Dog extends Animal { public void talk() { System.out.println("I am Dog!"); } public static void main(String[] args) { Animal animal = new Animal(); Cat cat = new Cat(); Dog dog = new Dog(); animal.talk(); cat.talk(); dog.talk(); } } ``` 代码运行结果: ```java I am Animal! I am Cat! I am Dog! ``` **多态是指由于继承和重写机制,相同类型的对象调用相同的方法,得到的结果可能不一样。** **在前面的例子中 `Dog` 对象和 `Cat` 对象我们都可以认为是 `Animal` 对象,他们都在调用talk()方法,但是结果可能不一样,这是因为每个子类对象都可能会重写了这个方法。** --- ## 结语 今天的文章就讲到这里,如果大家想了解更多关于 继承 的知识可以翻阅 Java 的[官方文档](https:/https://img.qb5200.com/download-x/docs.oracle.com/javase/tutorial/java/IandI/index.html)。 祝大家生活愉快!LOL

加载全部内容

相关教程
猜你喜欢
用户评论