龙生九子-浅谈Java的继承

书接上回,我们之前谈过了类和对象的概念,今天我来讲一讲面向对象程序设计的另外一个基本概念—继承


目录

  • 为什么需要继承
  • 自动转型与强制转型
  • 继承能干啥
  • 复写和隐藏
  • super关键字
  • 多态的概念

为什么需要继承

我们先先念一遍定义:利用继承,人们可以基于已存在的类构造一个新类。继承已存在的类就是复用(继承)这些类的方法和属性。在此基础上,还可以添加一些新的方法和属性,以满足新的需求。这是Java程序设计中的一项核心技术。

举个简单例子。俗话说 龙生九子,各有所好 ,我们把 龙王 当成父类,他有九个儿子,相当于九个子类。每个子类都继承了父辈的真龙血脉(欧拉!),但是他们各有不同,擅长做不同的事情,相当于子类实现了新的方法和属性,以满足不同的需求。而且需要注意的是九子只有一个爸爸,也就是一个子类只能继承一个父类,不允许认多个爸爸(龙王:逆子!)。

举一个更贴近生活的例子。我们有一个Employee类来表示公司的员工,这个公司中经理的待遇与普通雇员的待遇存在这一些差异。不过,他们之间也存在这很多相同的地方例如,他们都领薪水。只是普通的员工在完成本质工作后仅领取薪水,而经理在完成了预期的业绩之后还能得到奖金。这种情况就需要使用继承。这是因为需要为经理定义一个新类Manager,以便增加一些新功能。但可以重用Employee类中已经编写的部分代码。

码来!

//创建一个Manager类继承employee类
//关键字:extends(继承)
public class Manager extends Employee
{
private double bonus;
...//此处省略
public void setBonus(double bonus)
{
this.bonus = bonus;
} }

关键字extends表明正在构造的新类派生于一个已存在的类。我们可以看到,我们新建了一个 Manager类,他继承了 Employee类。那么,我们称 Employee父类Manager子类

自动转型和强制转型

父慈子孝

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.

补充说明:方法的 签名 由,方法名和参数类型构成。

calculateAnswer(double, int, double, double)

复写和隐藏

接下来我们介绍一下,复写和隐藏的概念。

码来:

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。再分别调用它的静态方法和实例方法。

结果如下:

第一行,我们用 myCat调用了静态方法,所以打印出了The static method in Cat

我们把 myCat 自动转型后再次调用静态方法,结果发现,他调用的是父类的静态方法。

我们称此为隐藏,调用的结果取决于他是子类还是父类,当子类调用静态方法时,父类的静态方法被隐藏

我们看到最后一行,明明我们是用父类的实例调用的 testInstanceMethod(),结果打印的是Cat,为什么呢?原因是父类的实例方法被复写了。只要他是子类的实例,调用实例方法只会得到子类的复写方法

  • 总结

    父类的实力方法 父类的静态方法
    子类的实例方法 Overrides(复写) Generates a compile-time error
    子类的静态方法 Generates a compile-time error Hides(隐藏)

我相信有同学会问:那有没有什么法子调用父类的实例方法呢?答:有,那就是 super关键字!

super关键字

废话少说,看代码:

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();
}
}

我们得到如下结果:

Printed in Superclass.
Printed in Subclass.
My name is: son. My id is: 1234

我们可以看到,我们使用了 super关键字来调用 父类的 printMethod方法。

那么 super还能干吗呢,我们还可以用super来调用 父类的构造方法。

我们看到这行代码:

public Subclass(String name,String id){
super(name);
this.id = id;
}

其中的 super(name); 就调用了父类的构造方法,复用了代码,减少冗余代码。十分方便!

注意:如果我们没有在第一行写 super语句,编译器会自动调用父类的 无参构造方法

如果你的父类没写无参构造方法,编译器会报错!

多态

字典中的多态性的定义是指生物学中的一种原理,其中生物或物种可以具有许多不同的形式或阶段。 该原理也可以应用于面向对象的编程和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();
}
}

代码运行结果:

I am Animal!
I am Cat!
I am Dog!

多态是指由于继承和重写机制,相同类型的对象调用相同的方法,得到的结果可能不一样。

在前面的例子中 Dog 对象和 Cat 对象我们都可以认为是 Animal 对象,他们都在调用talk()方法,但是结果可能不一样,这是因为每个子类对象都可能会重写了这个方法。


结语

今天的文章就讲到这里,如果大家想了解更多关于 继承 的知识可以翻阅 Java 的官方文档

祝大家生活愉快!LOL

龙生九子-浅谈Java的继承的更多相关文章

  1. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  2. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  3. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  4. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  5. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

  6. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  7. 浅谈Java中的final关键字

    浅谈Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  8. 浅谈Java中set.map.List的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  9. 【转】浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

随机推荐

  1. Linux Ubuntu 查看IP

    一.第一种方式:ifconfig -a 1.打开命令终端:Crtl + Alt + T 2.执行命令:ifconfig -a 如果你没有安装net-tools工具,则出现如下显示: (没有找到'ifc ...

  2. haproxy笔记之二:HAProxy简介

    HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持 ...

  3. JavaWeb中遇到的字符编码问题

    一.常见的编码方式 1.UTF-8 2.ISO-8859-1 二.Tomcat的编码问题 Tomcat8和7的编码方式 Tomcat7对URI默认编码是ISO-8859-1 Tomcat8对URI默认 ...

  4. Codeforces Round #612 (Div. 2)C. Garland

    第四次写题解,请多指教! http://codeforces.com/contest/1287/problem/C题目链接 题目大意是有一个数字串挂有1-n n个数字,现在上面缺失了一些数字,让你找出 ...

  5. 6487. 【GDOI2020模拟02.29】列强争霸war

    题目描述 区间绝对众数 即出现次数>len/2下取整的数 对于区间[L,R]扫一遍,维护一个数x和出现次数s 当前数=x则s+1,否则s-1,若s已为0则把x设为当前数 若区间内存在绝对众数,那 ...

  6. org.springframework.jdbc.UncategorizedSQLException: ### Error updating database. Cause: java.sql.SQLException: Incorrect string value: '\xE2\x80\x8B\xE2\x80\x8B...' for column 'pro_backgroud' at row

    如果你在mysql数据库中,将所有的表的编码格式设置成为utf-8之后还是不行,那就试试这个吧:ALTER TABLE your_database_name.your_table CONVERT TO ...

  7. UIView绘制原理,异步绘制

    绘制原理 首先看一幅流程图 UIView调用setNeedsDisplay方法后,实际上并没有发生当前视图的绘制工作,而是在之后的某一时机进行绘制工作,为什么会在之后的某一时机进行绘制工作呢? 当UI ...

  8. Java Web环境配置

    准备工作 jdk-8u241 apache-tomcat-9.0.31-windows-x64.zip Eclipse IDE for Enterprise Java Developers 关于版本选 ...

  9. Django+Nginx+Uwsgi环境配置

    nginx.conf : server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.acces ...

  10. Eureka 注册中心看这一篇就够了

    服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串.路由信息等.服务注册中心是微服务架构中最基础的设施之一. 在微服务架构流行之前,注册中心 ...