(一)父类和子类
子类:子类是作为另一个类的扩充或修正而定义的一个类。通过继承而得到的类为子类。
父类:被继承的类为父类。
extends:继承的关键字。
Dog为子类,Animal为父类。
(二)继承的概念
注意:继承使得子类可以利用父类中定义的方法和变量,就像它们属于子类本身一样。
1.继承是面向对象程序设计语言的一个基本特征,通过继承可以实现代码的复用。如果一个类没有声明extends子句,则该类默认继承Object。
2.定义子类的语法:
class SubClass extends SuperClass {
}
3.父类包括所有直接或间接被继承的类
4.如果省略extends子句,则该类为Object的子类
5.Java中不支持多继承,支持多重继承。
6.子类可以继承父类中访问权限设定为public、protected和default的成员变量和方法,但是不能继承访问权限为private的成员变量和方法。
(1)使用子类对象调用父类
//被继承的父类
public class Animal {
String name;
private int age;
String type;
String sex;
public void eat() {
}
public void run() {
}
}
}
//继承的子类
public class Dog extends Animal {
String color;
public void lookDoor()
{
System.out.println("这是一条看门狗");
}
}
package com.soft.practice;
public class DogTest {
public static void main(String[] args) {
//通过继承,子类对象可以直接使用父类中非私有的方法和属性。
Dog dog =new Dog();
dog.color="黄色";
dog.eat();
dog.lookDoor();
}
}
(2)子类中调用父类
1.子类可以通过super关键字调用父类private以外的方法
2.调用方式
- 调用父类成员方法:super.方法名(参数);
- 调用父类构造方法:super(参数);
3.调用父类构造方法时应遵循的原则:
- 只能在子类构造方法中调用父类的构造方法
- 调用父类构造方法时,只能使用super(…)
- 不要在调用父类构造方法前放任何其他代码
- 如果子类中没有调用父类构造,会默认调用无参数的super()
4.父类和子类的构造方法的执行顺序,遵从先父类后子类。
5.在同一个构造方法中不能同时使用super或this调用其他构造方法
硬性要求:子类的构造方法中必须至少有一个通过super调用父类构造方法。
package com.soft.practice;
import com.soft.javase.Animal;
public class Dog extends Animal {
String color;
public void lookDoor() {
//run(),eat()都是父类Animal中定义好的
super.run();
super.eat();
System.out.println("这是一条看门狗");
}
}
若子类中调用父类中的属性,该属性只在父类中存在时,此时子类和父类公用一个成员的属性地址。例:
//动物父类
public class Animal {
protected String name;
protected int age;
// 构造方法
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = 20;
}
}
public class Dog extends Animal {
String type;
String sex;
int age;
// 构造方法
public Dog() {
}
public Dog(String type,String sex,int age,String name)
{
super(name,age);
this.sex=sex;
this.type=type;
this.age=age;
this.name=name;
}
public void show() {
System.out.println("狗的年龄为"+age+"\t"+"狗的年龄为"+super.age);
System.out.println("狗的种类为"+name+"\t"+"父亲的年龄为"+super.name);
}
}
输出结果:
狗的年龄为12 狗的年龄为20
狗的种类为哈利 父亲的年龄为哈利
(3)父子类调用的情况先后顺序
1.父类的static变量和static初始化块
2.子类的static变量和static初始化块
3.父类的实例变量、初始化块
4.父类的构造方法
5.子类的实例变量、初始化块
6.子类构造方法
//父类
public class SuperClass {
static {
System.out.println("这是父类的静态代码块");
}
{
System.out.println("这是父类的实例化代码块");
}
/*
* 创建一个构造方法
*/
public SuperClass() {
System.out.println("这是父类的无参构造方法");
}
public SuperClass(String name) {
System.out.println("这是父类的有参构造方法");
}
}
//子类
public class SubClass extends SuperClass {
static {
System.out.println("这是子类的静态代码块");
}
{
System.out.println("这是子类的实例化代码块");
}
/*
* 创建构造方法
*/
public SubClass() {
System.out.println("这是子类的无参构造方法");
}
public SubClass(String name) {
super(name);
System.out.println("这是子类的有参构造方法");
}
}
//测试类
package com.soft.practice;
public class Test {
public static void main(String[] args) {
SubClass sub = new SubClass();
}
}
最终生成结果:
这是父类的静态代码块
这是子类的静态代码块
这是父类的实例化代码块
这是父类的无参构造方法
这是子类的实例化代码块
这是子类的无参构造方法