【Java基础学习笔记】6、类和接口(继承和抽象类)


一、类的继承

(1)继承的概念

 正如生活中的实例一样,任何事物所属的类型不是单一的,例如狮子属于动物,又属于食肉动物。而羚羊也属于动物,但属于食草动物。不论食肉动物还是食草动物,都有动物的特性,归属于动物这一类。这就需要用到继承来创建具有等级层次的类。
 继承就是子类通过继承来获得父类的特性、行为,使子类对象拥有父类的作用域和方法,使子类具有和父类相同的行为
 简单来说,父类更通用,子类更具体。

(2)继承格式

class 父类{

}
class 子类 extends 父类{

}
代码示例:

public class father {
    
    //父类
    int age;//父类的成员变量
    double height,weight;
    public father(){
    
    }//父类无参构造器
    public father(int age,double height,double weight){
    
    
    //父类有参构造器
        this.age=age;
        this.height=height;
        this.weight=weight;
    }
    //父类的方法
    public void getup(){
    
    
        System.out.println("起床了");
    }
    public void print(){
    
    
        System.out.println("年龄:"+age+",身高:"+height+"cm,体重:"+weight+"kg");
    }
}


public class son extends father{
    
    //子类 继承 父类
//没有写成员变量 是因为子类已经从父类继承了成员变量
    public son(){
    
    }//子类无参构造器
    public son(int age,double height,double weight){
    
    
    //子类有参构造器 用super调用父类构造器
        super(age,height,weight);
    }

}

public class javaexample {
    
    //测试类
    public static void main(String[] args) {
    
    
        son xiaoming = new son(15,170,60);//创建子类对象
        xiaoming.getup();//调用父类方法
        xiaoming.print();//调用父类方法 可以看到继承的成员变量
    }
}
//三个类写在了同一个包内

结果如下:
在这里插入图片描述
 如代码所示,虽然父类中可能写了很多成员变量及方法,但是子类中的代码十分简洁明了,当有数量庞大的类中拥有相同的代码块时,可以将相同部分提取出来组成一个父类。这样不仅能提高代码可读性,还增加了代码的复用性,也方便了以后的维护使用。

(3)继承类型

 Java支持单继承和多重继承,但不支持多继承。即A类可以继承B类;可以A类继承B类,C类继承B类注意不能形成闭环);也可以B类和C类都继承A类。但不能继承多个类,即A类不能同时继承B类和C类。(亲爹只能有一个)

(4)继承的特点

1、子类拥有父类的非 private 属性、方法。(不包括构造方法

2、子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

3、子类可以用自己的方式实现父类的方法。(方法的重写

4、提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

(5)关键字

extends关键字

 extends用于实现类的继承。类的继承是单一的,也就是说一个子类只能拥有一个父类,所以 extends 只能继承一个类。
 所有的类都是继承于 java.lang.Object,当一个类没有extends关键字,则默认继承Object类,这个类在 java.lang 包中,所以不需要 import。代码示例如(2)

super关键字

 如同this一样,super指的是超类,即父类。this调用的是当前类的方法与成员变量和属性,super则调用继承的父类的方法和成员变量和属性。
 值得注意的是,子类拥有的是父类非private的成员变量、属性和方法,但是可以调用的是父类非private的成员变量、属性、方法和构造方法。(构造方法是爹借给儿子的,不是继承)代码示例如(2)

(6)抽象类

 用abstract修饰的类,具有类的一般作用,但是无法实例化,可以看作信息不足不足以实例化的类。抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。抽象类表示的是一种继承关系,一个类只能继承一个抽象类
用(2)的代码稍作修改,进行示例:

public abstract class father {
    
    
//现在父类变成了抽象类
    int age;//所有成员变量和属性都可以使用
    double height,weight;
    public father(){
    
    }//无参和有参构造器都可以使用
    public father(int age,double height,double weight){
    
    
        this.age=age;
        this.height=height;
        this.weight=weight;
    }
    //普通方法也可以使用
    public void getup(){
    
    
        System.out.println("起床了");
    }
    public void print(){
    
    
        System.out.println("年龄:"+age+",身高:"+height+"cm,体重:"+weight+"kg");
    }
    //抽象方法 没有方法体 ()后面直接跟分号
    public abstract void walk();
}

public class son extends father{
    
    
//子类继承抽象类
    public son(){
    
    }//构造器任然可以调同父类构造器
    public son(int age,double height,double weight){
    
    
        super(age,height,weight);
    }
    //注意!必须重写抽象类中的抽象方法!
    public void walk(){
    
    
        System.out.println("走路");
    }
}

public class javaexample {
    
    
    public static void main(String[] args) {
    
    
    //实例化子类对象  父类是抽象类 抽象类无法实例化
        son xiaoming = new son(15,170,60);
        //调用各个方法 都可以使用
        xiaoming.getup();
        xiaoming.print();
        xiaoming.walk();
    }
}

结果如下:
在这里插入图片描述

抽象方法和方法重写

抽象方法:如上面代码所示,抽象方法即用abstract修饰的方法,其只有修饰词、方法名和(),没有方法体。继承抽象类之后,必须重写抽象类中的抽象方法,除非声明自己也是抽象类才可以不重写。(抽象类继承抽象类)
方法重写:子类继承父类中的方法后,可以在自己的类中重新编写该方法,返回值和形参都不能改变。(外表不变,内心不同)
方法重写规则:
1、参数列表与被重写方法的参数列表必须完全相同

2、返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类。

3、访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为protected。

4、父类的成员方法只能被它的子类重写。

5、声明为 final 的方法不能被重写。(留坑待填)

6、声明为 static 的方法不能被重写,但是能够被再次声明。(留坑待填)

7、子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

8、子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

9、重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。(留坑待填)

10、构造方法不能被重写。

11、如果不能继承一个类,则不能重写该类的方法。

重写和重载的区别

重载 重写
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
异常 可以修改 可减少删除,不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)

二、接口的继承

(1)接口的概念

 上面讲到,Java中并不能让一个类继承多个类,但是当我们想要让一个类“一口吃成一个胖子”该怎么办?这时候可以使用接口。
 接口是一种抽象类型,一个类通过继承一个接口,从而实现接口里所有的抽象方法。接口不是类,尽管二者编写方式很相似。类描述的是对象的属性和方法,而接口则包含类要实现的方法。

(2)接口的特点

1、接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有抽象方法。接口既是一种便利,也是一种约束。

2、接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

3、接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

4、接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

5、接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

(3)接口和类的异同

相同之处:
1、一个接口可以有多个方法。
2、接口文件保存在 .java 结尾的文件中,文件名使用接口名。
3、接口的字节码文件保存在 .class 结尾的文件中。
4、接口相应的字节码文件必须在与包名称相匹配的目录结构中。
不同之处:
1、接口不能用于实例化对象。
2、接口没有构造方法。
3、接口中所有的方法必须是抽象方法。
4、接口不能包含成员变量,除了 static 和 final 变量。
5、严格意义上接口不是被类继承了,而是要被类实现。
6、接口支持多继承。

(4)接口和抽象类的区别

1、抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

2、抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

3、 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

4、一个类只能继承一个抽象类,而一个类却可以实现多个接口。(干爹可以认多个)

(5)接口的声明

interface 接口名 [可选 extends 其他接口名]{
    声明变量
    抽象方法
}
代码示例:

public interface animal {
    
    
    public void eat();//抽象方法
    public void sleep();
}
interface lion extends animal{
    
    
	//接口继承接口
    public void hunt();//自己的抽象方法
}

(6)接口的实现

接口必须在一个类中实现,让这个类重写接口的所有抽象方法。
代码示例:

public interface animal {
    
    
    public void eat();
    public void sleep();
}
interface lion extends animal{
    
    
    public void hunt();
}


public class lionking implements lion{
    
    
	/*虽然只实现了lion接口,
	但是lion继承了animal,
	所以二者的抽象方法都需要重写
	*/
    public void eat(){
    
    
        System.out.println("吃肉");
    }
    public void sleep(){
    
    
        System.out.println("打盹");
    }
    public void hunt(){
    
    
        System.out.println("打猎");
    }
}

public class javaexample {
    
    
    public static void main(String[] args) {
    
    
        lionking simba=new lionking();//实例化类
        simba.hunt();
        simba.eat();
        simba.sleep();//调用方法
    }
}

//代码写在同一个包中

结果如下:
在这里插入图片描述

多接口继承

一个类只能继承一个父类,但是接口可以继承多个接口,extends后可以跟多个其他接口。

interface rabbit extends animal,furry,herbivorous……{
    
    
		抽象方法1;
		抽象方法2;
		……
}

猜你喜欢

转载自blog.csdn.net/qq_53743140/article/details/114276247