浅谈Java抽象类和接口的个人理解
Java是一门面向对象编程语言,面向对象编程的三大特性是封装、继承和多态。抽象类和接口都是Java中体现多态的机制。
抽象类
抽象类是不能被实例化的类,它通常被用于抽象出多个类中的共性并定义出它们的方法名、参数列表、返回类型和访问类型,由其子类来实现这些方法。
抽象类的定义方式为:
public abstract class AbstractClass {
//抽象方法,不包含具体实现
public abstract void abstractMethod();
//普通方法,包含具体实现
public void nonAbstractMethod() {
System.out.println("This is a non-abstract method");
}
}
抽象类可以包含抽象方法和非抽象方法,抽象方法没有实际的方法体,而非抽象方法则有方法体,可以被子类直接继承或重写。
当一个子类继承抽象类时,必须实现它继承的所有抽象方法,否则这个子类也必须被声明为抽象类。
public class SubClass extends AbstractClass {
@Override
public void abstractMethod() {
System.out.println("This is an implementation of abstractMethod in SubClass");
}
}
public class AnotherSubClass extends AbstractClass {
@Override
public void abstractMethod() {
System.out.println("This is just another implementation of abstractMethod in AnotherSubClass");
}
}
接口
接口是一种特殊的抽象类,它只包含了抽象方法和常量的定义,在接口中所有的方法都是抽象方法,没有被实现的方法体。
接口的定义方式为:
public interface Interface {
//抽象方法,不包含具体实现
void abstractMethod();
//默认方法,提供具体实现
default void defaultMethod() {
System.out.println("This is a default method in Interface");
}
}
接口中的方法默认是public和abstract的,可以省略这两个关键字。接口还可以定义默认方法和静态方法。默认方法必须有方法体,静态方法只能通过接口名称来调用,不能通过实现该接口的对象来调用。
一个类可以实现多个接口,实现接口时需要实现接口中所有的抽象方法。
public class ClassImpl implements Interface1, Interface2 {
@Override
public void abstractMethod() {
System.out.println("This is an implementation of abstractMethod in ClassImpl");
}
@Override
public void defaultMethod() {
System.out.println("This is a special implementation of defaultMethod in ClassImpl");
}
}
public interface Interface1 {
void abstractMethod();
}
public interface Interface2 {
void abstractMethod();
void defaultMethod();
}
抽象类和接口的选择
- 抽象类往往更适合于一些相对比较复杂、变化不确定的场景,抽象类可以定义一些共性的方法和属性,使得其子类可以很容易地继承和扩展,同时不必反复编写这部分代码。
- 接口则更适合于一些稳定、简单、无需扩展的场景,接口中只提供对外公开的方法的定义,可以保证实现该接口的类都有相同的方法和参数。一个类实现多个接口可以达到复合多种接口的目的。
示例一:抽象类
假设有一个动物类Animal,其中有一些通用的属性和方法,如颜色、体重、eat()方法等,这些是可以放在一个父类里面实现,并对其进行抽象化,用于多个子类继承。猪类Pig、狗类Dog、猫类Cat都可以继承父类Animal,实现自身的属性和方法。
public abstract class Animal {
private String color;
private double weight;
public abstract void eat();
}
public class Pig extends Animal {
@Override
public void eat() {
System.out.println("Pig eat corn");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog eat meat");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat eat fish");
}
}
示例二:接口
假设我们要实现一个图形类Shape,其中有一个求面积的方法getArea()和一个求周长的方法getPerimeter(),但我们并不知道实现这个图形类的子类会有哪些,因此我们可以使用接口来进行定义。正方形类Square、圆形类Circle、矩形类Rectangle都可以实现该接口,并且根据图形的特性分别实现自己的getArea()和getPerimeter()。
public interface Shape {
double getArea();
double getPerimeter();
}
public class Square implements Shape {
private double length;
public Square(double length) {
this.length = length;
}
@Override
public double getArea() {
return length * length;
}
@Override
public double getPerimeter() {
return length * 4;
}
}
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public double getPerimeter() {
return 2 * Math.PI * radius;
}
}
public class Rectangle implements Shape {
private double length;
private double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
public double getArea() {
return length * width;
}
@Override
public double getPerimeter() {
return 2 * (length + width);
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Java抽象类和接口的个人理解 - Python技术站