Java面向对象三大特征——继承

类的继承

    • 什么是继承呢?
    • 如何继承
    • Java继承中要注意的问题:
    • 继承中变量访问的特点
    • 方法重写
    • super关键字
    • Object类

什么是继承呢?

我们先来观察一下这俩个类(为了方便演示,先不对类进行封装)
Dog类

public class Dog {
	int age;
	String name;
	public void shout() {
		System.out.println("发出叫声");
	}
}

Cat类

public class Cat {
	int age;
	String name;
	public void shout() {
		System.out.println("发出叫声");
	}
	public void eat() {
		System.out.println("吃东西");
	}
}

这个两个类Dog类和Cat类,他们除了类名不同以外,其他代码完全一致。他们都有着相同的属性:name,age。他们都有着共同的行为:shout,eat。既然Dog和Cat都有着相同的属性和行为,那么我们就可以把他们归为一类,Animal类,让Dog类和Cat类都沿用Animal中的变量和方法。这就叫做继承,Animal为父类,Dog类和Cat类为子类。

如何继承

继承要用到关键字extends

extends
格式:class 子类 extends 父类 {
}

通过继承,可以使我们的代码变得简洁明了,并且容易维护,如果想修改一处属性,那么只需要在父类中修改即可。
下面是继承后的代码:
Animal类

public class Animal {
	int age;
	String name;
	public void shout() {
		System.out.println("发出叫声");
	}
	public void eat() {
		System.out.println("吃东西");
	}
}

Dog类

public class Dog extends Animal{

}

Cat类

public class Cat extends Animal{

}

这样一来,Dog类和Cat类就继承了Animal类。
我们在测试类中创建一个Dog对象和一个Cat对象,就可以对父类中的变量和方法进行调用了。
Java面向对象三大特征——继承_第1张图片

Java继承中要注意的问题:

1.Java只支持单继承,如下的代码是错误

class A{}
class B{}
class C extends A,B{}

2.多个类可继承一个类

class A{}
class B extends A {}
class C extends A {}

3.允许多重继承

class A {}
class B extends A {}
class C extends B {}

继承中变量访问的特点

我们将父类中的name成员变量赋值为"动物"

public class Animal {
	int age;
	String name = "动物";
	public void shout() {
		System.out.println("发出叫声");
	}
	public void eat() {
		System.out.println("吃东西");
	}
}

再在Dog类中定义一个String型的name,并赋值为"旺财"

public class Dog extends Animal{
	String name = "旺财";
}

在测试类中输出name,那么他的值应该是多少呢?
Java面向对象三大特征——继承_第2张图片
控制台输出的值为"旺财"
如果仅在Dog类中定义一个name,不赋值,观察控制台的输出情况

public class Dog extends Animal{
	String name;
}

Java面向对象三大特征——继承_第3张图片
这时输出的值为null
这就说明,继承中变量的访问特点为,先在子类中寻找该成员变量,并优先使用子类中有的成员变量,如果在子类中找不到该成员变量,再到父类中寻找。

方法重写

猫和狗在行为上有着不同的特点,如狗的叫声为“旺旺”,而猫的叫声为“喵喵”;狗吃的是骨头,而猫吃的是鱼。如果再调用用Animal类中的方法显然就不会合适。
在继承中,子类会自动继承父类的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写,重写的方法要与父类中被重写的方法的方法名、参数列表、以及返回值类型相同。
下面我们就对shout方法和eat方法进行重写

public class Dog extends Animal{
	@Override
	public void shout(){
		System.out.println("狗汪汪叫");
		}
}

只需要以相同的方法名、参数列表、返回值类型,在子类中把自己想要的功能写出即可。
在重写方法的上方加入@Override,编译器可自动检测方法重写的是否正确,若错误后自动报错。
Java面向对象三大特征——继承_第4张图片
在测试类中调用重写后的方法,即运行重写后的方法,父类中被重写的方法不会被执行。
Java面向对象三大特征——继承_第5张图片
注:重写方法时,不能使用比被重写方法更加严格的访问权限,如父类方法的访问权限是public,子类重写后就不能是private。

super关键字

根据前面的知识,测试类调用对象的成员方法和成员变量时,会优先在子类中寻找。那么如果我们想要使用父类中的成员方法和变量,该怎么办呢?Java中专门为我们提供了一个关键字:super

super

  1. super.成员变量 //调用父类的成员变量
  2. super.成员方法(参数) //调用父类的成员方法
  3. super(参数) //调用父类的构造方法
    但调用构造方法时要注意,只能在构造方法中使用this调用构造方法,不可在成员方法中调用,且this调用构造方法必须是该方法的第一条执行,并且只能出现一次。

super的使用方法可以类比于this关键字。

在父类中定义一个带参构造法

public class Animal {
	int age;
	String name;
	public Animal(int age){
		System.out.println("父类带参构造法");
	}
	public void shout() {
		System.out.println("发出叫声");
	}
	public void eat() {
		System.out.println("吃东西");
	}
}

此时子类必须有一个带参构造法,否则会报错。原因是在子类的构造方法中,一定会调用父类的某个构造方法,当父类中产生了带参构造法后,默认的无参构造法就会消失,所以子类必须写一个带参构造法。
Java面向对象三大特征——继承_第6张图片
修改后的Dog类:

public class Dog extends Animal{
	public Dog(int age) {
		super(age);  //继承父类的带参构造法
		System.out.println("子类带参构造法");
	}
	@Override
	public void shout(){
		System.out.println("狗汪汪叫");
		super.shout();  //调用父类的方法
		}
}

super(age)调用了父类中的带参构造法,super.shout调用了父类中的shout方法。来看测试类运行后的结果
Java面向对象三大特征——继承_第7张图片
创建对象时,调用子类的带参构造法,但是子类的带参构造法的第一条执行了父类的带参构造法,所以输出了父类带参构造法,然后输出子类带参构造法。
在子类的shout方法中调用了父类中的shout方法,所以会输出一个“发出叫声”。

Object类

在Java中,Object类是所有类的父类,所有的类都直接或间接的继承自Object类。Object类又称为超类,基类或根类。
既然类都继承自Object类,那么Object类中的方法也是可以被重写的。
如果我们直接调用toSring方法,返回的结果会是一串地址
Java面向对象三大特征——继承_第8张图片
在Dog类中重写toString方法

public class Dog extends Animal{
	@Override
	public String toString (){
		return "我是Dog类";
	}
	public Dog(int age) {
		super(age);  //继承父类的带参构造法
		System.out.println("子类带参构造法");
	}
	@Override
	public void shout(){
		System.out.println("狗汪汪叫");
		super.shout();  //调用父类的方法
		}
}

Java面向对象三大特征——继承_第9张图片
重写后的toString方法就完成啦。

小问题:为什么构造方法不写时,默认为无参构造呢?
答:因为Object类中含有无参构造法,而所有类都直接或间接的继承自Object类,所以构造法不写时就是继承了Object类中的无参构造法。

你可能感兴趣的:(java,开发语言)