抽象类 (Abstract)、接口 (Interface)
1. 抽象类 (Abstract)
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,那么这样的类称为抽象类。
使用 abstract 修饰符来表示抽象方法和抽象类。
这里创建一个表示图形的抽象类 Shape,语法格式:
1 abstract class Shape { 2 3 // 成员变量不能用 abstract 修饰 4 public int width; 5 public int height; 6 7 // 构造方法不能声明为抽象方法; 8 public Shape(int width, int height) { 9 this.width = width; 10 this.height = height; 11 } 12 13 // 声明抽象方法,计算面积 14 public abstract double area(); 15 16 // 抽象类里可以有非抽象方法 17 public void test() {} 18 public static void test2(String name) {} 19 20 }
抽象类的特点:
1) 抽象类不能被实例化,抽象类的非抽象子类可以被实例化;
2) 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类;
3) 抽象类中的抽象方法只是方法声明,不包含方法实现;
4) 抽象类有构造方法,但不能声明为抽象方法;
5)抽象类中的类方法(static 方法)不能声明为抽象方法;
6) 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类;
7) 抽象类的成员变量不能用 abstract 修饰,变量和常量按一般类的规则定义;
2. 接口 (Interface)
抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的 “抽象类” - 接口(Interface)。
接口是 Java 中最重要的概念之一,它可以被理解为一种特殊的类,由常量和抽象方法组成。
接口不是类,编写接口的方式和类很相似,但是它们属于不同的概念。
语法格式,代码:
1 interface Animal { 2 3 // 成员变量不能用 abstract 修饰, 4 // 隐式声明为 public static final, 需要被初始化 5 String name = "Animal"; 6 7 String getName(); // 成员方法隐式声明为 public abstract 8 } 9 10 interface Action { 11 void walk(); 12 }
1) 接口的特点
(1) 接口没有构造方法,不能被实例化;
(2) 接口不能继承类,也不能被类继承,可以被类实现(implements);
(3) 接口可以继承接口,可以同时继承多个接口,接口的多继承特点弥补了类的单继承;
(4) 接口的成员方法隐式声明为 public abstract,不能定义非抽象方法,不能声明 static 方法;
(5) 接口的成员变量隐式声明为 public static final, 即常量,需要初始化;
(6) 接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
2) 接口的继承
接口可以继承接口,可以同时继承多个接口,子接口继承父接口的方法。
使用 extends 关键字,实例:
// 单继承
interface Mammal extends Animal {
}
// 多继承
interface Mammal extends Animal, Action {
}
3) 接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
使用 implements 关键字,代码:
1 class Dog implements Mammal { 2 3 public String getName() { 4 return "Animal"; 5 } 6 7 public void walk() { 8 } 9 }
4)接口和抽象类的区别
(1) 抽象类里可以定义非抽象方法,接口中的方法必须是抽象方法;
(2) 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型(即常量);
(3) 抽象类是可以有静态代码块和静态方法(static 修饰的方法),接口中不能含有静态代码块以及静态方法,而;
(4) 一个类只能继承一个抽象类,而一个类却可以实现多个接口;
实例:
1 public class App { 2 3 public static void main( String[] args ) { 4 5 Square square = new Square(10, 8); 6 Triangle triangle = new Triangle(4, 5); 7 8 System.out.println("Square area :" + square.area()); 9 System.out.println("Triangle area: " + triangle.area()); 10 square.test(); 11 triangle.test(); 12 triangle.test2("Triangle"); 13 14 // Interface 15 Dog dog = new Dog(); 16 17 System.out.println("Dog.getName(): " + dog.getName()); 18 dog.walk(); 19 } 20 } 21 22 //////////////////////////////////////////// 23 // 抽象类 (Abstract) 24 25 abstract class Shape { 26 27 // 成员变量不能用 abstract 修饰 28 public int width; 29 public int height; 30 public String name; 31 public static String label = "Static variable"; 32 33 // 构造方法不能声明为抽象方法 34 //public abstract Shape(); 35 36 public Shape(int width, int height) { 37 this.width = width; 38 this.height = height; 39 } 40 41 // 声明抽象方法,计算面积 42 public abstract double area(); 43 44 // 抽象类里可以有非抽象方法 45 public void test() { 46 System.out.println("Shape(" + name + "): test()"); 47 } 48 public static void test2(String name) { 49 System.out.println("Shape(" + name + "): test2() -> " + Shape.label); 50 } 51 52 // 类方法不能声明为抽象方法 53 //public static abstract void testStatic(); 54 } 55 56 class Square extends Shape { 57 public Square(int width, int height) { 58 super(width, height); 59 super.name = "Square"; 60 } 61 62 // 重写父类中的抽象方法,计算正方形面积 63 @Override 64 public double area() { 65 return width * height; 66 } 67 } 68 69 class Triangle extends Shape { 70 public Triangle(int width, int height) { 71 super(width, height); 72 super.name = "Triangle"; 73 } 74 75 // 重写父类中的抽象方法,计算三角形面积 76 @Override 77 public double area() { 78 return 0.5 * width * height; 79 } 80 81 } 82 83 //////////////////////////////////////////// 84 // 接口 (Interface) 85 86 interface Animal { 87 88 // 成员变量变量都隐式声明为 public static final, 需要初始化 89 String name = "Animal"; 90 91 // 成员变量不能声明为 protected 和 private 92 //protected int a = 1; 93 //private int b = 2; 94 95 /* 96 // 接口没有构造方法 97 public Animal() { 98 99 } 100 */ 101 102 String getName(); // 成员方法隐式声明为 public abstract 103 104 // 接口里不能定义非抽象方法 105 //void test() {} 106 107 // 接口里不能声明 static 方法 108 //static void test2(); 109 110 } 111 112 interface Action { 113 114 void walk(); 115 116 } 117 118 interface Mammal extends Animal, Action { 119 120 } 121 122 class Dog implements Mammal { 123 124 public String getName() { 125 return Animal.name; 126 } 127 128 public void walk() { 129 System.out.println("Dog: walk()"); 130 } 131 132 }
输出:
Square area :80.0
Triangle area: 10.0
Shape(Square): test()
Shape(Triangle): test()
Shape(Triangle): test2() -> Static variable
Dog.getName(): Animal
Dog: walk()