文章目录
一、基本含义
1.1 创建
继承语法:
[访问控制修饰符] [非访问控制修饰符] class 子类名 extends 父类名{ 类体 }
项目 | 含义 |
---|---|
含义 | 继承父类的属性和方法。 |
目的 | 复用代码。便于维护。 |
父类别名 | 基类或者超类。 |
特性 | 单继承(即子类只有一个父类,父类可以有多个子类) |
Object类 | Java中,是所有的类的父类。 |
![](https://img-blog.csdnimg.cn/20181210095928359.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpemVuZ2Jhbw==,size_16,color_FFFFFF,t_70)
1.2 调用
1.2.1 调用父类方法——未被重写后
项目 | 含义 |
---|---|
直接访问父类 | 非private修饰的属性和方法 |
间接访问父类 | private 修饰的属性和方法 |
1.2.1 调用父类方法——被重写后
语法:super.父类被重写方法名();
子类重写父类:
项目 | 含义 |
---|---|
目的 | 继承父类时,展现特性。 |
别名 | 覆盖(override) |
重写父类 | 一大两小两同 |
访问控制修饰符 | 不小于父类 |
非访问控制修饰符 | 不限 |
返回值类型 | 不大于父类 |
抛出的异常类 | 不大于父类 |
方法名 | 与父类相同 |
参数列表 | 与父类相同 |
1.2.1 调用父类方法——构造器
语法:
[ 访问控制修饰符 ] [ 非访问控制修饰符 ] 类名{ super(参数列表);…}
注意:
- 同一构造器中,super(参数)必须放置有效执行方法体首行。
- 同一构造器中,super(参数)只能出现一次。
- 同一构造器中,super(参数)必须出现一次。
- 同一构造器中,super只能出现在子类的方法体中。
- 同一构造器中,只能引用一个构造器。
- 同一构造器中,this(参数)和super(参数)只能出现一个。
特别提醒:
若父类显式声明只有有参构造器,而子类未调用显式有参构造器,则会出错。
1.3 继承初始化顺序
(1)先父类初始化,后子类初始化。
(2)先属性初始化,后构造方法初始化。
Animal类:
public class Animal{
public String name;
public int age = 1;
public Animal(){
System.out.println("先创建父类对象");
age = 2;
}
public void eat(){
System.out.println("动物吃");
}
}
Dog狗类:
public class Dog extends Animal{
public Dog(){
System.out.println("后创建子类对象");
}
@Overwrite
public void eat(){
System.out.println("小狗吃");
}
}
Initail类:
public class Initail{
public static void main(String[] args){
Dog dog = new Dog(); //先初始化父类,再初始化子类。
// 结果:"先创建父类对象" + "后创建子类对象"
dog.eat();
// 结果:"小狗吃"
System.out.println(dog.age); //先对象中的属性初始化,再构造方法初始化。
// 结果:2
dog.age = 3;
System.out.println(dog.age); //先父类初始化,后子类初始化。
// 结果:3
}
}
1.4 初始化块执行顺序
静态初始化块 → 普通初始化块 → 构造函数初始化块。
静态初始化块的特点:1.只在类加载时执行,且仅仅执行一次。2.只能给静态变量赋值。
public class HelloWorld{
int num1;
int num2;
static int num3;
// 构造函数。
public HelloWorld(){
num1 = 1;
System.out.println("构造");
}
// 普通初始化块。
{
num2 = 2;
System.out.println("普通");
}
// 静态初始化块。
static{
num3 = 3; // 只能给静态变量赋值。
System.out.println("静态");
}
public static void main(String[] args){
HelloWorld h = new HelloWorld();
// 结果:"静态" + "普通" + "构造"。
System.out.println(h.num1);
System.out.println(h.num2);
System.out.println(h.num3);
// 结果:1 + 2 + 3。
HelloWorld h2 = new HelloWorld(); // 只在类加载时执行,且仅仅执行一次。
// 结果:"普通" + "构造"。
}
}
二、具体操作
主函数入口源文件:
public class MainEntrance{
public static void main(String[] args){
Rabbit rb = new Rabbit("小白兔", 1, 3, "雄");
// 封装属性调用:
System.out.println(rb.getName()); // 外部类调用,子类的父类的封装属性。
// rb.setLegNumber();
System.out.println(rb.getAge()); //
rb.eat();
}
}
动物类源文件:
public class Animal{
// 封装属性:动物共性,名字和年龄。
private String name;
private int age;
/* 构造器:无参。
* 被调用:子类构造器必须调用父类构造器。
* 此处目的:防止子类没有调用父类有参构造函数时,报错情况发生。
*
*/
public Animal(){
}
public Animal(int age){
// 封装属性调用:本类中,this.私有变量名。
this.age = age;
}
public Animal(String name, int age, String sex){
// 封装属性调用:本类中,this.私有变量名。
this.name = name;
this.age = age;
this.sex = sex;
}
// 对象方法:
public void eat(){
System.out.println(this.name + "也需要吃东西" );
}
public void sleep(){
System.out.println(this.name + "已经" + this.age + "岁了!");
}
public void life(){
System.out.println("每个动物都有声明!");
}
// set和get方法:通过创建此两种方法,让外部类访问被封装的属性。
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
兔子类源文件:
public class Rabbit extends Animal{
private int legNumber;
/*
* 构造器
* 同一构造器中,只能引用一个构造器。
* 同一构造器中,this(参数)和super只能出现一个。
* 同一构造器中,super(参数)必须出现一次。
* 同一构造器中,super(参数)只能出现一次。
* 同一构造器中,super(参数)必须放置有效执行方法体首行。
* 同一构造器中,super只能出现在子类的方法体中。
* 若父类显式声明只有有参构造器,而子类未调用显式有参构造器,则会出错。
*/
public Rabbit(String name, int age, int legNumber, String sex){
super(name,age,sex);
judgeLegNumber(legNumber);
// this(legNumber); // 同一构造器中,this(参数)和super只能出现一个。
}
// 重载构造器:其它相同,只是参数列表和方法体不同。
public Rabbit(int legNumber){
super(legNumber);
}
// 重写父类方法:两大一小两同原则。
public void eat(){
super.eat(); // 调用父类的对象方法。
System.out.println(super.getName() + "是食草动物!"); // 调用父类封装的属性。
System.out.println(this.sex + "兔跑得快吗?"); // 调用父类未封装的属性。也可省略this。
}
// 对象方法:
public void judgeLegNumber(int legNumber){
if(legNumber != 4){
System.out.println("这不是一个正常的兔子!");
}else{
this.legNumber = legNumber;
}
}
// get方法和set方法:帮助外类获取封装的属性。
public int getLegNumber() {
return legNumber;
}
public void setLegNumber(int legNumber) {
this.legNumber = legNumber;
}
}