文章目录
- 一、重新定义需求
- 二、继承
- 1. 继续分析
- 2. 概念
- 3. 代码
- ① 父类
- ② 子类
- ③ 测试结果
- 4. 饿狼传说之多层继承
- ① 概念
- ② 代码
- 5. 多继承
- 三、方法的重写
- 1. 情境
- 2. 代码
- ① 吃什么
- ② 怎么叫(Override重写)
- 3. 小结
- 四、super
- 1. 啃老
- 2. 啃老啃到底
- 五、final
- 1. 用途及特征
- 2. 举例理解
- ① 修饰类
- ② 修饰方法
- ③ 修饰成员变量
- 补充
- 3. 更通俗地理解
- 六、内容出处
一、重新定义需求
你的程序火了以后,又有大爷大妈来找你了。他们说,不能光给养狗的写啊,也得考虑一下他们这些养猫的、养仓鼠的人啊。
这个问题该怎么解决呢?总不能给每种宠物都写一个程序吧,那得把人累死。或者说在当前程序里再定义一些cat类、Hamster类等,定义完怎么办呢,又得重新定义姓名、年龄、品种、食物、吃喝拉撒这些属性,这是不是太麻烦了。
二、继承
1. 继续分析
我们可以再想一下,猫、狗、仓鼠是不是都是动物啊。而且它们都有姓名、年龄、品种、吃喝拉撒这些属性,这些属性也恰好是所有动物的共性。
既然如此,我们是不是可以把这些共性抽离出来给Animal这个类,再让Cats、Dogs、Hamsters去继承Animal里面的东西。这样一来,就不需要重复定义了。相当于又从一个更高的维度去看待问题了。
2. 概念
继承描述是父和子的关系。共性的部分抽离出来,放在父类(如:Animal类)里,子类(如:Cats类)保存特性(如:猫需要猫砂)。
通俗一点就是上梁不正下梁歪(虽然是贬义词,但是凑合着理解吧)、这孩子跟ta爸一模一样。
写法:子类 extends 父类
3. 代码
① 父类
直接从原来的Dogs类里剪切🤣
package com.practice.bean;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Animal {
private String name;
private int age;
private String variety;
private String food;
private static String plot = "NanG";
public static String getPlot(){
return plot;
}
// 无参构造器
public Animal(){
}
// 有参构造器
public Animal(String name, int age, String variety, String food) {
this.name = name;
this.age = age;
this.variety = variety;
this.food = food;
}
public Animal(String name, String variety){
this.name = name;
this.variety = variety;
}
public Animal(String name){
this.name = name;
}
public void setAge(int age){
if(age < 0 || age > 30){
System.out.println("输入数据不合法, 已为您自动清零");
this.age = 0;
}else{
this.age = age;
}
}
public int getAge(){
return this.age;
}
public void eat() {
System.out.println(this.name + "吃饭!");
this.sleep();
}
public void sleep() {
System.out.println(this.name + "睡觉!");
}
void crazy() {
System.out.println(this.name + "发疯");
}
// //不合理
// private String plot = "NanG";
// public String getPlot(){
// return this.plot;
// }
public static void injection(){
System.out.println("所有的动物, 月底打针!");
}
}
② 子类
③ 测试结果
由此可见,狗、猫和仓鼠类确实继承了Animal类里的东西。虽然也可以直接创建一个Animal的实例,但是说实话意义不大。
4. 饿狼传说之多层继承
① 概念
通俗来说就是,灰太狼从他太太太爷爷那一辈就吃不到羊,他继承了这个基因,所以他也没吃到羊。
② 代码
Animal和Dogs类没做任何改动
5. 多继承
多继承:联想一下骡子(马和驴的杂交种,同时具备马和驴的共性)。
java不支持多继承
三、方法的重写
1. 情境
如图所示,上述程序可以王阿姨家的狗和张大爷家的猫在吃饭和在喊叫。但是我现在想知道它们吃的是什么?怎么叫的?
2. 代码
① 吃什么
显然,王阿姨和张大爷可以自己决定家里的宠物吃什么。因此可以借助food这个成员变量,通过传参数区分宠物的食物。
② 怎么叫(Override重写)
王阿姨和张大爷肯定不能决定自己家的宠物怎么叫啊,所以刚刚传参的方式肯定不适用。这个时候就要用到重写了。
3. 小结
① 在子类当中,凡是@Override注解下面的方法一定是来自于它父类的,但是它又不学它的父亲。比如说灰太狼有天确实吃到羊了,不走他父亲的老路了。
② 子类自己认为,必须打破他父亲的传统,进行革新,革新的内容就是方法体,于是它重新写了父类的方法。例如王阿姨家的狗可以汪汪叫了,张大爷家的猫可以喵喵叫了,发展了自己的特性,没必要都动物叫了。
③ 快捷键:alt + insert -> Override Methods
四、super
1. 啃老
那我子类重写了父类的方法,但是我要是还想使用父类的方法该怎么办呢?通俗来说就是,我不想自己赚钱自己花了,我想直接花我爹的。放到该案例中就是,王阿姨家的狗说我不想汪汪叫了,我就乐意动物叫。
alt + insert -> Override Methods 可快速生成重写方法。
这样一来,王阿姨家的狗就不是汪汪叫了,开始动物叫了。
2. 啃老啃到底
继承本身是不能继承父类的构造方法的。通俗来讲就是,啃老不能说连爸爸的脸也一起照搬弄到自己脸上,这是很难的。那我如果我非要这么做怎么办呢?还得靠super
例如:我现在可以初始化一个动物实例(因为Animal类里有相关的构造方法),但是没有办法初始化一个狗的实例(Dogs类里没有相关的构造方法)。
现在要开始啃老了。
快捷键:alt + insert -> Constructor(Override Methods也可以) -> 全选(找到构造方法, 然后选择) -> 回车
发现可以了
五、final
1. 用途及特征
① 用途:修饰类;修饰方法;修饰成员变量
② 特征:final意为最终,也就是说断子绝孙了。final修饰的类已经是最底层了,后面没人继承它了,它也不能被继承;final修饰的方法不可以被子类重写,但是可以仍旧被子类使用;final修饰的成员变量的值后续不可以被更改了。
2. 举例理解
① 修饰类
显然,拉布拉多已经是我们这个程序的最底层了。没有动物会再继承它了,此时我们就可以用final修饰它。
随意新建一个类去验证一下,发现拉布拉多这个类确实不能被继承。
② 修饰方法
我们知道拉布拉多是一种导盲犬。因此我们可以在Dogs类里面写一个类似的方法,再在Labrador类里重写一下。
此时如果用final修饰Dogs类里的这个导盲方法,就会发现Labrador类无法重写这个方法了。
但是拉布拉多犬仍然可以使用这个方法,只不过返回的也是false了。
③ 修饰成员变量
用static修饰小区名以后,虽然外部不能更改了,但是仍然无法防止程序员自身手误导致该变量值被更改。
这样一来,拉布拉多发个疯就把小区名给改了,太荒谬了吧。怎么办呢?用final修饰这个成员变量
补充
① 根据阿里开发手册的要求,我们用plot表示小区名显然不太合理。可以改成text_community_name,text指的是该变量的实际用途(虽然这样写也不太合适,但凑合着看),而且要全部大写。
② idea全部大写快捷键:Ctrl + Shitf + u
3. 更通俗地理解
假设A是一个富豪,B是ta的孩子。正常情况下B是可以继承A所有东西的。
但是A觉得B太败家了,又不孝顺,因此不想给B一点遗产。这种情况下,就可以直接用final修饰A这整个类。
A转念一想,B毕竟是自己的孩子,万一ta以后想改过自新了呢,总要给孩子留点退路,不能逼太紧。于是,A就把车子、房子留给B了。但是思虑再三后决定,不能给B过多现金,ta可以定期拿一部分作为生活费,但是不能为所欲为。这种情况下,A就在自己这个类里写了一个getMoney()方法,并且用final修饰了。
A为了防止B把房子卖了,于是把地契都给烧了。这个时候,就可以用final修饰home这个成员变量。
六、内容出处
java