抽象与接口的理解

Posted tunan-ki

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象与接口的理解相关的知识,希望对你有一定的参考价值。

继承的概念

继承描述的是事物之间的所属关系,通过继承可是使多种事物之间形成一种关系体系
类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。在程序中,如果想声明一个类继承另一个类,需要使用extends关键字

class Animal{
    String name;
    public void show() {
        System.out.println(name+"发出了叫声");
    }
}
//Dog类继承自Animal类
class Dog extends Animal{
    //打印一个name的方法
    public void printName() {
        System.out.println("这个动物现在是"+name);
    }
}
public class Example01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name="老黑";
        dog.printName();
        dog.show();    
    }
}

注 意:
1. 在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类
2. 多个类可以继承同一个父类
3. 在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类
4. 在Java中,子类和父类是一种相对概念,也就是说一个类是某个父类的同时,也可以是另外一个类的子类。

重写父类方法

在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型

class Animal{
    public void show() {
        System.out.println("发出了叫声");
    }
}
//Dog类继承自Animal类
class Dog extends Animal{
    @Override     //重写父类show()方法
    public void show() {
        System.out.println("汪汪汪");
    }
}
public class Example01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.show();
    }
}

注 意:
子类重写父类方法时,不能使用父类中被重写的方法更严格的访问权限,如:父类中的方法是public的,子类的方法就不能是private的

super关键字

Java中专门提供了一个super关键字用来访问父类的成员

1. 使用super关键字访问父类的成员变量和成员方法

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

案例学习

 

class Animal{
            String name="动物";
            public void show() {
                System.out.println(name+"发出了叫声");
            }
        }
        //Dog类继承自Animal类
        class Dog extends Animal{
            String name="黑狗";
            //打印一个name的方法
            public void printName() {
                System.out.println("这个动物现在是"+super.name);
            }
            @Override
            public void show() {
                super.show();
            }
        }
        public class Example01 {
            public static void main(String[] args) {
                Dog dog = new Dog();
                dog.printName();
                dog.show();        
            }
        }

 

2. 使用super关键字访问父类的构造方法,注意通过super调用父类的构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次

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

class Animal{
    //定义Animal的有参构造
    public Animal(String name) {
        System.out.println("我是一只"+name);
    }
}
class Dog extends Animal{
    public Dog() {
        super("老王");    //调用父类有参的构造方法
    }
}
public class Example02 {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}

在定义一个类时,如果没有特殊需求,尽量在类中定义一个无参的构造方法,避免被继承时出现错误

 final关键字

final关键字可用于修饰类、变量和方法,它有"无法改变"或者"最终"的含义,因此被finnal修饰的类、变量和方法具有以下特性:

1. finnal修饰的类不能被技能
2. finnal修饰的方法不能被子类重写
3. finnal修饰的变量(成员变量和局部变量)是常量,只能赋值一次

抽象类

Java允许在定义方法时不写方法体。不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰

    abstract void show();                 //定义抽象方法show()

当一个类中包含了抽象方法,该类必须使用**abstract**关键字来修饰,使用abstract关键字修饰的类为抽象类

//定义抽象类Animal
abstract class Animal{
    abstract int show();
}

在定义抽象类时需要注意,包含抽象方法的类必须声明为抽象类,但抽象类可以不包含任何抽象方法,只需使用abstract关键字来修饰即可。另外,抽象类时不可以被实例化的,因为抽象类中有可能包含抽象方法,抽象方法是没有方法体的,不可以被调用。如果想调用抽象类中定义的方法,则需要创建一个子类,在子类中将抽象类中的抽象方法进行实现

//定义抽象类
abstract class Animal{
    abstract void show();
}
//定义Dog类继承抽象类Animal
class Dog extends Animal{
    @Override
    void show() {
        System.out.println("这是重写的抽象类");
    }
}
public class Example01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.show();
    }
}

接口

如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方法来定义,即接口。接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象

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

在一个接口中可以有多个父接口,它们之间用逗号隔开。Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口。接口中的变量默认使用"public static final"来修饰,即全局常量;接口中定义的方法默认使用"public abstract"来修饰,即抽象方法。如果接口声明为public,则接口中的变量和方法全部为public

由于接口中的方法都是抽象方法,因此不能通过实例化对象的方法来调用接口中的方法,此时需要定义一个类,并使用implements关键字实现接口中所有的方法。一个类可以在继承另一个类的同时实现多个接口,这些接口在implements子句中要是用英文逗号(,)隔开。接口的实现类声明格式如下

    [<修饰符>] class<类名> [extends <超类名>]  [implements <接口1>,<接口2>,...]
//定义Animal接口
interface Animal{
    //定义全部变量,其默认修饰为public static final
    String ANIMAL_BEHAVIOR="动物的行为";
    //定义抽象方法breathe(),其默认修饰为public abstract
    void breathe();
    //定义抽象方法run
    void run();
}
//Dog类实现了Animal的接口
class Dog implements Animal{
    @Override
    public void breathe() {
        System.out.println(ANIMAL_BEHAVIOR+"在玩耍");
    }
    @Override
    public void run() {
        System.out.println(ANIMAL_BEHAVIOR+"在奔跑");
    }
}
public class Example01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.breathe();
        dog.run();
    }
}

注意:一个类实现一个接口,必须给出接口中所有方法的实现,如果不能实现某方法,也必须写出一个空方法

在程序中还可以定义一个接口使用extends关键字去继承另一个接口

//定义animal接口
interface Animal{
    //定义全部常量,其默认修饰为public static final
    String ANIMAL_BEHAVIOR = "动物的行为";
    //定义抽象方法breathe(),其默认修饰为public abstract
    void breathe();
    //定义抽象方法run();
    void run();
}
//定义了LandAnimal接口
interface LandAnimal extends Animal{
    void liveOnLand();
}
//定义Dog类实现Animal接口
class Dog implements LandAnimal{
    //实现breath方法
    @Override
    public void breathe() {
        System.out.println(ANIMAL_BEHAVIOR+": 狗在呼吸");
    }
    //实现run方法
    @Override
    public void run() {
        System.out.println(ANIMAL_BEHAVIOR+": 狗在奔跑");
    }
    //实现liveOnLand方法
    @Override
    public void liveOnLand() {
        System.out.println("狗是陆上动物");
    }
}
//测试类
public class Example01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        //使用对象名.常量名的方式输出接口中的常量
        System.out.println(dog.ANIMAL_BEHAVIOR);
        //使用接口名.常量名的方式输出接口中的常量
        System.out.println(Animal.ANIMAL_BEHAVIOR);
        dog.breathe();        //调用Dog类重写的breathe方法
        dog.run();            //调用Dog类重写的run方法
        dog.liveOnLand();    //调用Dog类重写的liveOnLand方法
    }
}

总结接口的特点:

1. 接口中的方法都是抽象的,不能实例化对象
2. 接口中的属性只能是常量
3. 当一个类实现接口时,如果这个类是抽象类,则实现接口中的部分方法即可,否则需要实现接口中的所有方法。
4. 一个类通过implements关键字实现接口时,可以实现多个接口,被实现的多个接口之间要用逗号隔开
5. 一个接口可以通过extends关键字继承多个接口,接口之间用逗号隔开
6. 一个类在继承另一个类的同时还可以实现接口,此时,extends关键字必须位于implements关键字之前

 

以上是关于抽象与接口的理解的主要内容,如果未能解决你的问题,请参考以下文章

Java 封装

Java 封装

深入delphi编程理解之接口接口与类的异同及接口的声明和实现

Java 封装

Java 封装

Java封装