1、继承
什么是继承呢?
先举一个例子,顾名思义,当一位老父亲要将自己的遗产给自己的儿子,那么这个时候儿子就有了父亲的所有资产,包含负债,但是儿子也可以重新分配父亲的资产这个就拉扯到重写父类的方法了,这里说的比较笼统,上代码
例如:现在有3个人,他们都有共同的特性例如吃饭,说话
package lianxi;
class People{
public void havingDinner(){
System.out.println("会吃饭");
}
public void speak(){
System.out.println("会说中文话");
}
}
//小红
class People1 extends People{
}
//小蓝
class People2 extends People{
}
//小白
class People3 extends People{
}
class Test{
public static void main(String[] args) {
//创建小红的实例
People1 People1=new People1();
People1.havingDinner();
People1.speak();
}
}
从上面的代码能看出,小红并没有创建吃饭,和说话功能,但是用了关键字 extends ,通过extends 继承了父类、人类(People)的本质,说话和吃饭,因为小蓝与小白都继承了People类 都是具有吃饭和说话的功能的,这里代码不一一的输出了,但是小蓝只会说英语怎么办呢,那么小蓝就需要重新定义父类(People)speak的方法
class People{
public void havingDinner(){
System.out.println("会吃饭");
}
public void speak(){
System.out.println("会说中文话");
}
}
//小红
class People1 extends People{
}
//小蓝
class People2 extends People{
public void speak(){
System.out.println("会说英语");
}
}
//小白
class People3 extends People{
}
class Test{
public static void main(String[] args) {
//创建小红的实例
/* People1 People1=new People1();
People1.havingDinner();
People1.speak();*/
//创建小蓝实例
People2 People2=new People2();
People2.havingDinner();
People2.speak();
}
}
小蓝类的speak()被重写后是可以输出的,但是有一个问题出现了,对应不同的人可能都会说不同的语言,它们只是有共同的行为,但是行为的本质不一样,如果目前这个父类定义了说话的方法体,当子类被继承后不需要被重写也拥有了父类会说中文的功能,如果小蓝只会说英语,在继承时并不知道父类是定义的只会说中文的功能,而只是知道继承了我便有了说话的功能,那么便不会堆小蓝说话功能进行重写,况且小蓝的说话功能便会出现故障。而且许多人说话的语言都不一样,就算知道父类是只会说中文,那么一次一次的继承与重写也不太符合面向对象的概念也会导致代码的冗余,因为父类就相当于多写了一个方法体,而继承的类继承了没必要的代码,还需要重写
于是怎么解决这个问题呢?
抽象类
依据上面的疑问,此时就出现了抽象类的概念,例如,如下的代码我们可以将 People定义为抽象类,而speak定义为抽象方法,不需要写方法体,并且要让继承的所有类,明白 知道,人类必须有的两种功能一种是吃饭,一种是说话,并且在创建没一个人的时候必须实现不同说话的语言(不然就报错),这个抽象类就像是定义的一种规范一样的,只是定义了每个人都要有这个功能,但是需要每一个人去实现该说话的功能并给出说明
abstract class People{
public void havingDinner(){
System.out.println("会吃饭");
}
public abstract void speak();
}
//小红
class People1 extends People{
@Override
public void speak() {
System.out.println("我是小红我只会说俄语");
}
}
//小蓝
class People2 extends People{
public void speak(){
System.out.println("我是小蓝我只会说英语");
}
}
//小白
class People3 extends People{
@Override
public void speak() {
System.out.println("我是小白我只会说中文");
}
}
class Test{
public static void main(String[] args) {
//创建小蓝实例 这里只是举例,无论创建任何实例 此时都可以输出不同的语言了
People2 People2=new People2();
People2.havingDinner();
People2.speak();
}
}
上面这个代码案例的 speak 在 People类被定义为抽象后,所有子类都必须要重新实现说话的功能,但是依然具有会吃饭的功能,而且父类的speak简化掉了,没有了方法体,但是明确告诉所有子类,必须要都实现说话功能,那么又延申一个问题,那这样和接口又有什么区别呢?
接口
接着上面的问题:例如小红是女生,而小白和小蓝是男生, 小红体能具有生孩子的功能,这个时候接口就衍生了,小红再继承了抽象类(People)后可以再去实现生孩子的接口,小红除开能生孩子以外,和其他的人一样都具备继承People的条件,但是不能将生孩子的接口强行的安到所有人生上,毕竟体制机能男生不能生孩子
abstract class People{
public void havingDinner(){
System.out.println("会吃饭");
}
public abstract void speak();
}
//小红
class People1 extends People implements children {
@Override
public void speak() {
System.out.println("我是小红我只会说俄语");
}
@Override
public void children() {
System.out.println("小红生了一个胖娃娃");
}
}
//小蓝
class People2 extends People{
public void speak(){
System.out.println("我是小蓝我只会说英语");
}
}
//小白
class People3 extends People{
@Override
public void speak() {
System.out.println("我是小白我只会数中文");
}
}
//创建生孩子接口类
interface children{
void children();
}
class Test{
public static void main(String[] args) {
People1 People1=new People1();
People1.havingDinner();
People1.speak();
People1.children();
}
}
这时候只是小红具备有比小白和小蓝多一项功能是生孩子,如果别的人类有不同的功能还可以去实现不同的接口,接口是可以定义多个的,但继承只能单继承
//小红
class People1 extends People implements children,HappyMarry {
@Override
public void speak() {
System.out.println("我是小红我只会说俄语");
}
@Override
public void children() {
System.out.println("小红生了一个胖娃娃");
}
@Override
public void HappyMarry() {
System.out.println("小红实现了HappyMarry接口 并结婚了");
}
}