java接口与抽象类详解

接口的概念:

在java程序设计语言中,接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。编写接口的方式和类很相似,但是它们属于不同的概念,类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在Java中,接口类型可用来声明一个变量,它们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类的区别:

  • 接口不能用于实例化对象
  • 接口没有构造方法
  • 接口中所有方法必须是抽象方法
  • 接口中不能包含成员变量,除了static和final变量
  • 接口不是被类继承,而是要被类实现
  • 接口支持多继承

接口特性:

  • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为public abstract
  • 接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final变量
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法

抽象类和接口的区别:

  • 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的
  • 接口中不能含有静态代码块以及静态方法,而抽象类是可以有静态代码块和静态方法
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口

重写接口中声明的方法时,需要注意以下规则:

  • 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常
  • 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型
  • 如果实现接口的类时抽象类,那么就没必要实现该接口的方法

在实现接口的时候,也要注意一些规则:

  • 一个类可以同时实现多个接口
  • 一个类只能继承一个类,但是能实现多个接口
  • 一个接口能继承另一个接口,这和类之间的继承比较相似

抽象类:

如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用性,甚至可能更加抽象。从某种角度看,祖先类更加通用,人们只将它作为派生其他类的基类,而不作为想使用的特定的实例类。

例如,考虑以下对Employee类层次的扩展。一名雇员是一个人,一名学生也是一个人。Employee类和Student类都继承自Person。

为什么要花精力进行这样高层次的抽象呢?每个人都有一些诸如姓名这样的属性。学生和雇员都有姓名属性,因此可以将getName方法放置在位于继承关系较高层次的通用超类中。

现在,在增加一个getDescription方法,它可以返回对一个人的简短描述。例如:

an employee with a salary of $50000
a student majoring in computer science

在Employee类和Student类中实现这个方法很容易。但是在Person类中应该提供什么内容呢?除了姓名之外,Person类一无所知,当然,可以让Person.getDescription()返回一个空字符串。然而,还有一个更好的方法,就是使用abstract关键字,这样就完全不需要实现这个方法了。

// no implementation required
public abstract String getDescription();

为了提高程序的清晰度,包含一个或多个抽象方法的类本身必须被声明为抽象的。

public abstract class Person {
    public abstract String getDescription();
    // ....
}

除了抽象方法之外,抽象类还可以包含具体数据和具体方法。例如,Person类还保存着姓名和一个返回姓名的具体方法。

public abstract class Person {
    private String name;
    public Person(String name){
        this.name = name;
    }
    public abstract String getDescription();
    public String getName(){
        return name;
    }
}

抽象方法充当着占位的角色,它们的具体实现在子类中。扩展抽象类可以有两种选择。一种是在抽象类中定义部分抽象类方法或不定义抽象类方法,这样就必须将子类也标记为抽象类;另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了。

对于下面的实例,请牢记,由于不能构造抽象类(比如,Person)的对象,所以变量p永远不会引用Person对象,而是引用诸如Employee或Student这样具体子类对象,而这些对象中都定义了getDescripton方法。

// Person
public abstract class Person {
    public abstract String getDescription();
    private String  name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Employee:

import java.time.LocalDate;

public class Employee06 extends Person{

    private double salary;
    private LocalDate hireDay;

    public Employee06(String name, double salary, int year, int month, int day) {
        super(name);
        this.salary = salary;
        hireDay = LocalDate.of(year,month,day);
    }

    public double getSalary() {
        return salary;
    }

    public LocalDate getHireDay() {
        return hireDay;
    }

    @Override
    public String getDescription() {
        return String.format("an employee with a salary of $%.2f",salary);
    }

    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
}

Student:

public class Student extends Person{
    private String major;

    public Student(String name, String major) {
        // pass name to superclass constructor
        super(name);
        this.major = major;
    }
    @Override
    public String getDescription() {
        return "a student majoring in " + major;
    }
}

PersonTest:

public class PersonTest {
    public static void main(String[] args) {
        Person[] people = new Person[2];

        //fill the people array with Student and Employee objects
        people[0] = new Employee06("Herrry Hacker", 50000, 2021,6,1);
        people[1] =  new Student("Maria Morris", "Computer science");

        // print out names and descriptions of ass person objects
        for (Person p : people) {
            System.out.println(p.getName() + ", "+p.getDescription());
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值