Java学习总结(面向对象中类的类的继承、方法的重写、super关键字、final关键字、抽象类和接口)

文章详细介绍了Java中类的继承机制,包括子类如何继承父类,如何定义自己的属性和方法。接着讲解了方法的重写,以及super关键字的两种用途:访问父类的成员和调用父类构造器。此外,讨论了final关键字在类、方法和变量上的应用。最后,阐述了抽象类和接口的概念,包括如何使用它们以及它们之间的关系和区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、类的继承

类的概念

示例:子类是如何继承父类的

示例:子类也可以定义自己的属性和方法

二、方法的重写

示例:方法的重写

三、super关键字

(1)使用super关键字访问父类的成员变量和成员方法,具体格式如下

(2)使用super关键字访问父类中指定的构造方法,具体格式如下

四、final关键字

1、final关键字修饰类

2、final关键字修饰方法

3、final关键字修饰变量

五、抽象类和接口

1、抽象类

示例:抽象类的使用

2、接口

        接口使用interface关键字声明,语法格式如下

       定义接口的实现类,语法格式如下

示例:接口的使用

示例:演示一个类既实现接口,又继承抽象类的情况

示例:接口的继承


学习Java面向对象中类的类的继承、方法的重写、super关键字、final关键字、抽象类和接口

一、类的继承

类的概念

        类的继承是指在一个现有的类的基础上去构建一个新的类,构建出来的新类称为子类,现有称为父类。子类继承父类的属性和方法,使得子类对象(实例)具有父类的特此和行为。

       如果想声明一个类继承另一个类,需要使用 extends 关键字,

语法格式:

class 父类{
 ......
}
class 子类 extends 父类{
 ......
}

示例:子类是如何继承父类的

​package com.company.example01;

//定义(父类)Animal 类
class Animal{
    private String name;  //定义name属性
    private int age; //定义age属性
    //封装
    //获取name属性
    public String getName() {
        return name;
    }
    //设置name属性
    public void setName(String name) {
        this.name = name;
    }
    //获取age属性
    public int getAge() {
        return age;
    }
    //设置age属性
    public void setAge(int age) {
        this.age = age;
    }
}
//定义(子类)Cat类继承 Animal 类
class Cat extends Animal{
    //此处不写任何代码
}
//定义测试类
public class Example01 {
    public static void main(String[] args) {
        Cat cat = new Cat();  //创建一个Cat类的实例化对象
        cat.setName("波斯猫");  //此时访问的方法是父类中的,子类中并没有定义
        cat.setAge(3);  //此时访问的方法是父类中的,子类中并没有定义
        System.out.println("名称:"+cat.getName()+",年龄:"+cat.getAge());
    }
}
/*
结果是:
        名称:波斯猫,年龄:3
        */

示例:子类也可以定义自己的属性和方法

package com.company.example02;

//定义(父类)Animal 类
class Animal{
    private String name;  //定义name属性
    private int age; //定义age属性
    //封装
    //获取name属性
    public String getName() {
        return name;
    }
    //设置name属性
    public void setName(String name) {
        this.name = name;
    }
    //获取age属性
    public int getAge() {
        return age;
    }
    //设置age属性
    public void setAge(int age) {
        this.age = age;
    }
}

//定义(子类)Cat类继承 Animal 类
class Cat extends Animal{
    private String color; //定义color属性
    //设置color属性
    public String getColor() {
        return color;
    }
    //获得olor属性
    public void setColor(String color) {
        this.color = color;
    }
}

//定义测试类
public class Example02 {
    public static void main(String[] args) {
        Cat cat = new Cat();  //创建一个Cat类的实例化对象
        cat.setName("波斯猫");  //此时访问的方法是父类中的,子类中并没有定义
        cat.setAge(3);  //此时访问的方法是父类中的,子类中并没有定义
        cat.setColor("黑色");
        //打印
        System.out.println("名称:"+cat.getName()+",年龄:"+cat.getAge()+"岁,颜色:"+ cat.getColor());
    }
}
/*
结果是:
        名称:波斯猫,年龄:3岁,颜色:黑色
        */

       在类的继承中,需要注意一些问题,具体如下。

       (1)在Java中,类只支持单继承,不允许多继承。也就是说,一个类只能有一个直接父类,例如下面这种情况是不合法的。

class A { }
class B { }
class C extends A,B { }  // C类不可以同时继承A类和B类

        (2)多个类可以继承一个父类,例如下面这种情况是允许的。

class A { }
class B extends A{ }
class C extends A{ } // B类和C类都可以继承A类

         (3)在Java中多层继承也是可以的,即一个类的父类可以再继承另外的父类。例如,C类继承自B类,而B类又可以继承自A类,这时,C类也可称为A类的子类。例如,下面这种情况是允许的。

class A { }
class B extends A{ }  // B类继承A类,B类是A类的子类
class C extends B{ }  // C类继承B类,C类是B类的子类,同时也是A类的子类

       (4)在Java中,子类和父类是一种相对概念,一个类也可以是某个类的父类,也可以是另一个类的子类。例如,在第(3)种情况,B类是A类的子类,同时又是C类的父类。

       在继承中,子类不能直接访问父类中的私有成员,子类可以调用父类的非私有方法,但是不能调用父类的私有成员。

二、方法的重写

        在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表和返回值类型,且在子类重写的方法不能拥有比父类方法更加严格的访问权限。

示例:方法的重写

package com.company.example03;
//定义Phone类
class Phone{
    //定义打电话
    void call(){
        System.out.println("打电话");
    }
}
//定义NewPhone类
class NewPhone extends Phone{
    //重写父类Phone 中的call()方法
    void call(){
        System.out.println("开启语音");
        System.out.println("关闭语音");
    }
}
//测试类
public class Example03 {
    public static void main(String[] args) {
        System.out.println("------------重写前-----------");
        Phone phone = new Phone();  //实例化Phone类的对象
        phone.call();  //调用Phone对象call方法
        System.out.println("------------重写后-----------");
        NewPhone newPhone = new NewPhone(); //实例化NewPhone类的对象
        newPhone.call();  //调用NewPhone对象call方法
    }
}
/*
结果是:
        ------------重写前-----------
        打电话
        ------------重写后-----------
        开启语音
        关闭语音
        */

三、super关键字

        当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,Java提供了super关键字,super关键字可以在子类中调用父类的普通属性、方法和构造方法。

(1)使用super关键字访问父类的成员变量和成员方法,具体格式如下

super.成员变量
super.成员方法 (参数1, 参数2...)

示例:使用关键字super关键字访问父类的shout( ) 方法

​
package com.company.example05;
//定义Animal类
class Animal{
    String name = "牧羊犬";
    //定义动物叫的方法
    void shout(){
        System.out.println("动物发出叫声");
    }
}
//定义 Dog类继承 Animal类
class Dog extends Animal{
    //重写父类 Animal中的 shout( ) 方法,扩大了访问权限
    public void shout(){
        super.shout();  //调用父类 Animal类中的shout( ) 方法
        System.out.println("汪汪汪......");
    }
    public void printName(){
        System.out.println("名字:"+super.name); //调用父类 Animal类中的name属性
    }
}
//定义测试类
public class Example05 {
    public static void main(String[] args) {
        Dog dog = new Dog(); //创建 Dog类的实例对象
        dog.shout();  //调用dog重写的 shout( )方法
        dog.printName();  //调用 Dog类中的 printName()方法
    }
}

​

(2)使用super关键字访问父类中指定的构造方法,具体格式如下

super (参数1 ,参数2...)

示例:如何使用super关键字调用父类的构造方法

package com.company.example06;
//定义父类 Animal类
class Animal{
    private String name;
    private int age;
    //有参数构造方法
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //获取name属性
    public String getName() {
        return name;
    }
    //设置name属性
    public void setName(String name) {
        this.name = name;
    }
    //获取age属性
    public int getAge() {
        return age;
    }
    //设置age属性
    public void setAge(int age) {
        this.age = age;
    }
    //info( ) 方法
    public String info(){
        return "名称:"+this.getName()+",年龄:"+this.getAge();
    }
}
//定义 Dog类继承 Animal类
class Dog extends Animal{
    private String color;
    //有参数构造方法
    public Dog(String name, int age, String color) {
        super(name, age); //调用父类Animal类 属性
/*        //也可以这样写
        super.setName(name);
        super.setAge(age);*/
        this.color = color;
    }
    //获取color属性
    public String getColor() {
        return color;
    }
    //设置color属性
    public void setColor(String color) {
        this.color = color;
    }
    //重写父类的info( ) 方法
    public String info(){
        return super.info() +",颜色:"+this.getColor(); // 扩充父类中的方法
    }
}
//定义测试类
public class Example06 {
    public static void main(String[] args) {
        Dog dog = new Dog("牧羊犬",3,"黑色");  //创建 Dog类的实例对象
        System.out.println(dog.info());
    }
}
/*结果是:
        名称:牧羊犬,年龄:3,颜色:黑色
        */

注意:

       通过super( ) 调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次。

       super 与 this 关键字的作用非常相似,都可以调用构造方法、普通方法和属性,但是两者之间还是有区别的。

示例:super 与 this 的区别

        需要注意的是,this 和 super 两者不可以同时出现,因为 this 和 super在调用构造方法时都要求必须放在构造方法的首行。

四、final关键字

       final的英文意思是“最终”。在Java中,可以使用final关键字声明类、属性、方法,在声明时需要注意以下几点
(1)使用fnal修饰的类不能有子类。

(2)使用final修饰的方法不能被子类重写。

(3)使用final修饰的变量(成员变量和局部变量)是常量,常量不可修改。

1、final关键字修饰类

         Java中的类被 final 关键字修饰后,该类将不可以被继承,即不能派生子类。

错误示例:(编译器报错)

​//使用final 关键字修饰Animal类
final class Animal{
}
// Dog类继承Animal类
class Dog extends Animal{
}
//定义测试类
public class Example07 {
    public static void main(String[] args) {
        Dog dog = new Dog(); //创建Dog类的实例对象
    }
}

 

        第2行代码定义了Animal类并使用final关键字修饰,第5~6行代码定义了Dog类并继承Animal类。当Dog类继承使用final关键字修饰的Animal类时,编译器报 “ 无法从最终 cn.itcast.Animal 进行继承 ” 错误,即不能继承使用final修饰的Animal类。由此可见,被final关键字修饰的类为最终类,不能被其他继承。

2、final关键字修饰方法

       当一个类的方法被final关键字修饰后,这个子类将不能重写该方法。

错误示例:(编译器报错)

//定义Animal类
class Animal{
    //使用final关键字修饰shout()方法
    public final void shout(){
    }
}
//定义Dog类继承Animal类
class Dog extends Animal{
    //重写Animal类的shout()方法
    public void shout(){
    }
}
//定义测试类
public class Example08 {
    public static void main(String[] args) {
        Dog dog = new Dog(); //创建Dog类的实例对象
    }
}

运行结果

          第10行代码在Dog类中重写了父类Animal中的shout()方法,编译报错。这是因为Animal类的shout ()方法被final修饰,而被 final关键字修饰的方法为最终方法,子类不能对该方法进行重写。因此,当在父类中定义某个方法时,如果不希望被子类重写,就可以使用final关键字修饰该方法。

3、final关键字修饰变量

       Java中被final修饰的变量为常量,常量只能在声明时被赋值一次,在后面的程序中,其值不能被改变。
如果再次对该常量赋值,则程序会在编译时报错。

错误示例:(编译器报错)

public class Example09 {
    public static void main(String[] args) {
        final int AGE = 18;  //第一次可以赋值
        AGE = 20; //再次赋值会报错
    }
}

     当第4行代码对AGE进行第二次赋值时,编译器报错。原因在于使用final定义的常量本身不可被修改。

注意:

        在使用final声明变量时,要求全部的字母大写。如果一个程序中的变量使用 public static final 声明,则此变量将称为全局变量。

示例:

public static final String NAME = "哈士奇";

五、抽象类和接口

1、抽象类

        当定义一个类时,常常需要定义一些成员方法描述类的行为特征,但有时这些方法的实现方式是无法确定的。例如,前面在定义Animal类时,shout( )方法用于描述动物的叫声,但是不同动物的叫声是不同的,因此在shout( )方法中无法准确地描述动物的叫声。
        针对上面描述的情况,Java提供了抽象方法来满足这种需求。抽象方法是使用abstract关键字修饰的成员方法,抽象方法在定义时不需要实现方法体

抽象方法的定义格式如下

abstract 返回值类型 方法名称 (参数);

        当一个类包含了抽象方法,该类必须是抽象类。抽象类和抽象方法一样,必须使用abstract 关键字进行修饰。

抽象方法的定义格式如下

abstract class 抽象类名称{
   属性;
   访问权限 返回值类型 方法名称(参数) {  //普通方法
        return [返回值];
   }
   访问权限 abstract 返回值类型 抽象方法名称(参数);  //抽象方法,无方法体
}

        从以上格式可以发现,抽象类的定义比普通类多了一些抽象方法,其他地方与普通类的组成基本上相同。
抽象类的定义规则如下。
(1)包含抽象方法的类必须是抽象类。

(2)抽象类和抽象方法都要使用abstract关键字声明。

(3)抽象方法只需声明而不需要实现。

(4)如果一个非抽象类继承了抽象类,那么该子类必须实现抽象类中的全部抽象方法。

示例:抽象类的使用

package com.company.example10;
//定义抽象类 Animal
abstract class Animal{
    //定义抽象方法shout()
    abstract void shout();
}
//定义 Dog类继承抽象类Animal
class Dog extends Animal{
    //实现抽象方法shout()
    void shout(){
        System.out.println("汪汪汪.......");
    }
}
//定义 Cat类继承抽象类Animal
class Cat extends Animal{
    //实现抽象方法shout()
    void shout(){
        System.out.println("喵喵喵.......");
    }
}
//定义测试类
public class Example10 {
    public static void main(String[] args) {
        Dog dog = new Dog(); //创建 Dog类的实例对象
        dog.shout();  //调用 dog对象的shout()方法
        Cat cat = new Cat();  //创建 Cat类的实例对象
        cat.shout();  //调用 cat对象的shout()方法
    }
}
/*
结果是:
        汪汪汪.......
        喵喵喵.......*/

注意:

        使用abstract关键字修饰的抽象方法不能使用private修饰,因为抽象方法必须被子类实现,如果使用了private声明,则子类无法实现该方法。

2、接口

         如果一个抽象类的所有方法都是抽象的,则可以将这个类定义接口。接口是Java中最重要的概念之一。在JDK8中,接口中除了可以包括抽象方法外,还可以包括默认方法和静态方法(也叫类方法),默认方法使用default修饰,静态方法使用static修饰,且这两种方法都允许有方法体。

        接口使用interface关键字声明,语法格式如下

public interdace 接口名 extends 接口1, 接口2 ...{
   public static final 数据类型 常量名 = 常量值;
   public abstract 返回值类型 抽象方法名称 (参数列表);
}

        在上述语法中,“ extends接口1,接口2... ”表示一个接口可以有多个父接口,父接口之间用逗号分隔。Java使用接口的目的是克服单继承的限制,因为一个类只能有一个父类,而一个接口可以同时继承多个父接口接口中的变量默认使用“ public static final ”进行修饰,即全局常量接口中定义的方法默认使用“ public abstract ”进行修饰,即抽象方法如果接口声明为public,则接口中的常量和方法全部为public

注意:

        在很多Java程序中,经常看到编写接口中的方法时省略了public,有很多读者认为它的访问权限是default,这实际上是错误的。不管写不写访问权限,接口中方法的访问权限永远public。与此类似,在接口中定义常量时,可以省略前面的“public static final”,此时,接口会默认为常量添加“ public static final ”。
        从接口定义的语法格式可以看出,接口中可以包含三类方法,分别是抽象方法、默认方法、静态方法,其中静态方法可以通过“ 接口名.方法名 ”的形式来调用,而抽象方法和默认方法只能通过接口实现类的对象来调用。接口实现类的定义方式比较简单,只需要定义一个类,该类使用implements关键字实现接口,并实现了接口中的所有抽象方法。需要注意的是,一个类可以在继承另一个类的同时实现多个接口,并且多个接口之间需要使用英文逗号( , )分隔。

       定义接口的实现类,语法格式如下

修饰符 class 类名 implements 接口1, 接口2,...{
   ...
}

示例:接口的使用

package com.company.example11;
//定义接口 Animal
interface Animal{
    int ID =1;  //定义全局变量
    String NAME ="牧羊犬";  //定义全局变量
    void shout(); //定义抽象方法shout()
    //定义静态方法getID()
    static int getID(){
        return Animal.ID;
    }
    public void info(); //定义抽象方法info()
}
//定义抽象方法eat()
interface Action{
    public void eat();
}
//定义 Dog类实现 Animal接口和 Action接口
class Dog implements Animal,Action{
    //重写Action接口中的抽象方法 eat()
    public void eat(){
        System.out.println("喜欢吃骨头"); //方法体
    }
    //重写Animal接口中的抽象方法 shout()
    public void shout(){
        System.out.println("汪汪......");
    }
    //重写Animal接口中的抽象方法 info()
    public void info(){
        System.out.println("名称:"+NAME);
    }
}
//定义测试类
public class Example11 {
    public static void main(String[] args) {
        System.out.println("编号"+Animal.getID());  //使用Animal接口直接访问了Animal接口中的静态方法getId()
        //抽象、接口(接口是更加抽象的抽象类)不能直接实例化对象
        Dog dog = new Dog(); //创建Dog类的实例对象  Ctrl+Alt+v
        dog.info();
        dog.shout();  //调用Dog类中重写的shout()方法
        dog.eat();  //调用Dog类中重写的eat()方法
    }
}
/*结果是:
        编号1
        名称:牧羊犬
        汪汪......
        喜欢吃骨头
        */

       上述代码是类与接口之间的实现关系,如果在开发中一个类既要实现接口,又要继承抽象类,则可以按照以下格式定义类。

修饰符 class 类名 extends 父类名 implements 接口1, 接口2,...{
    ...
}

示例:演示一个类既实现接口,又继承抽象类的情况

package com.company.example12;

//定义接口 Animal
interface Animal{
    public String NAME ="牧羊犬";  //定义全局变量
    public void shout(); //定义抽象方法shout()
    public void info(); //定义抽象方法info()
}
//定义抽象方法eat()
abstract class Action{
    public abstract void eat();  //定义抽象方法eat()
}
//定义 Dog类继承 Action抽象类并实现 Animal接口
class Dog extends Action implements Animal {
    //重写Action抽象类中的抽象方法 eat()
    public void eat(){
        System.out.println("喜欢吃骨头"); //方法体
    }
    //重写Animal接口中的抽象方法 shout()
    public void shout(){
        System.out.println("汪汪......");
    }
    //重写Animal接口中的抽象方法 info()
    public void info(){
        System.out.println("名称:"+NAME);
    }
}
//定义测试类
public class Example12 {
    public static void main(String[] args) {
        //抽象、接口(接口是更加抽象的抽象类)不能直接实例化对象
        Dog dog = new Dog(); //创建Dog类的实例对象  Ctrl+Alt+v
        dog.info();  //调用Dog类中重写的info()方法
        dog.shout();  //调用Dog类中重写的shout()方法
        dog.eat();  //调用Dog类中重写的eat()方法
    }
}
/*
结果是:
        名称:牧羊犬
        汪汪......
        喜欢吃骨头
        */

          接口是不允许继承抽象类的,但是允许一个接口继承多个接口。

示例:接口的继承

package com.company.example13;

//定义接口 Animal
interface Animal{
    public String NAME ="牧羊犬";  //定义全局变量
    public void info(); //定义抽象方法info()
}
interface Color{
    public void black();  //定义抽象方法black()
}
interface Action extends Animal,Color{
    public void shout(); //定义抽象方法shout()
}
//定义 Dog类继承 Action抽象类并实现 Animal接口
class Dog implements Action {
    //重写Animal接口中的抽象方法 info()
    public void info(){
        System.out.println("名称:"+NAME);
    }
    //重写Color接口中的抽象方法 shout()
    public void black(){
        System.out.println("黑色");
    }
    //重写Action接口中的抽象方法 shout()
    public void shout(){
        System.out.println("汪汪......");
    }
}
//定义测试类
public class Example13 {
    public static void main(String[] args) {
        //抽象、接口(接口是更加抽象的抽象类)不能直接实例化对象
        Dog dog = new Dog(); //创建Dog类的实例对象  Ctrl+Alt+v
        dog.info();  //调用Dog类中重写的info()方法
        dog.shout();  //调用Dog类中重写的shout()方法
        dog.black();  //调用Dog类中重写的black()方法
    }
}
/*
结果:
        名称:牧羊犬
        汪汪......
        黑色
        */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值