java三大特性之继承
通过上一篇对封装的简介,相信大家对java三大特性的封装有了一定的了解。那么除了上一篇博客讲到的封装之外,继承也是java的一大特性。接下来我就谈谈我对java三大特性中的继承的一些看法。
继承的概念
继承是一种类与类的关系,是一种“is a”的关系。
打个比方,狗 “is a” 动物,这里就可以说动物类和狗类之间就是继承关系,也就是说狗类继承了动物类,这里就可以称狗类是“子类”、“派生类”,而动物类就叫做“父类”、“基类”。
而继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
需要注意的是 java中的继承是单继承。 也就是说,java的子类只能继承一个父类。就像我们的人一样,每个人只有一个亲生父亲。
继承的格式
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class Animal {
}
class Dog extends Animal {
}
另外,所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。
继承的好处
继承可以提高维护性,代码也更加简洁,提高代码的复用性
比个例子,西虹市首富中,沈腾因为继承了他的二爷的财产,从一个小混混一下子变成了西虹市首富,省去了很多年的奋斗。那么java中也一样,一个子类继承了父类,那么他就可以拥有父类的所有方法和属性。 (要注意,“private”修饰的是不能被继承的。) 我们把它称为代码的复用。代码的复用可以使子类省去写一些和其他类相同的属性和方法。
这么说或许大家不能清楚地get到继承的好处,接下来我们用代码来举个例子:
先写一个狗类:
public class Dog {
//狗的名字
private String name;
//狗的ID
private int id;
//构造方法
public Dog(String myName, int myid) {
name = myName;
id = myid;
}
//正在吃饭
public void eat(){
System.out.println(name+"正在吃");
}
//正在睡觉
public void sleep(){
System.out.println(name+"正在睡");
}
//自我介绍
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
然后创建一个猫类:
public class Cat {
//猫的名字
private String name;
//猫的ID
private int id;
//构造方法
public Cat(String myName, int myid) {
name = myName;
id = myid;
}
//正在吃饭
public void eat(){
System.out.println(name+"正在吃");
}
//正在睡觉
public void sleep(){
System.out.println(name+"正在睡");
}
//自我介绍
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
这么写大家就能看出来,这两个类基本上差不多,这么写是不是看起来特别繁琐,而且可维护性也很低,后期修改代码的时候很容易出错。而且这只是狗和猫两个类,如果加上了兔子、乌龟等等的类,那是不是更加繁琐了。所以说我们需要一种方法来简化代码,这种方法就是继承。
public class Animal {
//动物的名字
private String name;
//动物的ID
private int id;
//构造方法
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
//正在吃饭
public void eat(){
System.out.println(name+"正在吃");
}
//正在睡觉
public void sleep(){
System.out.println(name+"正在睡");
}
//自我介绍
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
//狗类
public class Dog extends Animal {
// 构造方法
public Dog(String myName, int myid) {
super(myName, myid);
}
}
//猫类
public class Cat extends Animal {
// 构造方法
public Cat(String myName, int myid) {
super(myName, myid);
}
}
这么写是不是简便多了呢?如果之后又很多的其他动物类,那么继承是不是显得更加有优势了呢?继承的好处大家一定可以get到了。接下来,我们了解一下继承中子类对父类方法的重写。
继承中,方法的重写
1.> 什么是方法的重写
如果子类对父类的方法不满意,是可以重写父类的方法的。而且当调用方法时,优先调用子类的方法。
就像上面距离过的那几个类,如果有了一个猫头鹰类,它的在别人吃饭的时候它在睡觉,所以他在eat方法里要写成“name + “正在睡””,name这样他就需要重写Animal的方法。
2.> 方法重写的语法规则
返回值类型,参数类、个数及顺序,方法名都必须与父类的方法相同。这样才能叫做方法的重写。
谈到继承中方法的重写,我们有必要介绍几个关键字
继承中几个重要的关键字
1.> extends 关键字
这个关键字上面已经提到过用法了,我们不再重复。但有必要在一次强调,extend只能继承一个父类。
2.> implements 关键字
那如果想写机器人这个类,我们它除了继承动物类之外,还想让它继承机械类和计算机类,那么这时候我们就用到了接口这个概念。这里我们先简单提一下,具体我们在下一篇博客java三大特性之多态中细谈。接口和继承一样都可以使类拥有别的类的属性或者方法,只不过接口可以继承多个接口,而实现接口的关键字就是implement。
3.> super 关键字
比如说我们需要引用一个父类的方法,但是子类和父类的方法名是一样的,优先调用的是子类的方法。或者说,父类的属性和子类的属性名字重复了,是不是我们就没有办法来调用弗父类的属性、方法了呢?这个时候我们就可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
4.> this 关键字
this关键字相对比于super,this关键字表示对本对象的引用。
我们以代码来说明super和this的区别:
// 父类
class SuperClass {
// 属性i
int i = 50;
}
// 子类
class SubClass extends SuperClass {
// 属性i
int i =100;
// 测试方法
public void showMessage() {
System.out.printf("super.i = " + super.i + "," + " this.i = " + this.i);
}
}
// 测试类
public class SuperDemo {
public static void main(String []args) {
new SubClass().showMessage();
}
}
运行结果很明显:super.i = 50, this.i = 100。
final 关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法。我们提到他是为了强调,用final修饰后,该方法不能被子类重写。实例变量也可以被定义为 final,被定义为 final 的变量也是不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final
这些就是一些关于继承需要了解的关键字。
最后我们来总结一下java三大特性中继承的特性
继承的特性
- 子类拥有父类非private的属性,方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。
(关于耦合度:耦合性也叫块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块之间越独立则越差,模块间耦合的高低取决于模块间接口的复杂性,调用的方式以及传递的信息。)