抽象类与接口是Java中最重要部分之一,这里用较大的篇幅来做下这部分的笔记.
1. final关键字
在Java中, 可以使用final关键字修饰类、方法以及成员变量。
(1).final标记的类不能被继承;
(2).final标记的方法不能被子类复写;
(3).final标记的变量即成为常量,只能被赋值一次.
注意: 如果使用final来声明常量,请遵守以下常规: final标记的变量名,所有单词字母都需大写.
2. 抽象类
讲抽象类的定义必须先讲抽象方法的定义. 所谓抽象方法,是指只声明而未实现(即没有{}包围的方法体)的方法. 而含有一个或多个抽象方法的类就称为抽象类.
抽象类 = 普通类 + 抽象方法
对于抽象类,时刻需要谨记: 抽象类是不能够直接实例化的, 如果要使用一个抽象类,就必须要有该抽象类的子类. 如果抽象类的子类不是抽象类的话,就一定要复写该抽象类的所有抽象方法.
如下面代码示例:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | abstract class Person { //全局常量的命名一定要采取全部字母大写的方式 public static final String NAME = "newsainton" ; //print()方法有方法体,所以不是抽象方法 public void print() { System.out.println( "非抽象方法中,Name = " +NAME); } //fun()方法不含方法体,为抽象方法 public abstract void fun(); } //B类继承自A类,但B未声明为抽象类,则必须要复写A类中所有的抽象方法 class Student extends Person { public void fun() { System.out.println( "抽象方法中,Name = " + super .NAME); } } public class Demo01 { public static void main(String args[]) { Student s = new Student(); s.fun(); s.print(); } } |
另外一个需要考虑的问题是: 抽象类可否有自己的构造方法?
答案是: 抽象类中允许有自己的构造方法,但是该构造方法并不能直接实例化自己的对象. 如果在抽象类中存在有参构造方法,则必须在子类中明确的使用super([参数列表])指明要调用父类中的哪个构造方法.
这里举例如下:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | abstract class Person { // 应该有姓名和年龄属性 private String name ; private int age ; public Person(){} // 如果已经不是无参的,则必须在子类中明确调用无参构造 public Person(String name, int age) { this .name = name ; this .age = age ; } public String getName() { return this .name ; } public int getAge() { return this .age ; } // 定义一个输出方法,但是此方法为抽象方法 public abstract String getInfo() ; } class Student extends Person { public Student(String name, int age) { // 调用Person类中有两个参数的构造方法 super (name,age) ; } public String getInfo() { return "姓名 = " + super .getName()+ ",年龄 = " + super .getAge() ; } } public class Demo05 { public static void main(String args[]) { Student s = new Student( "张三" , 30 ) ; System.out.println(s.getInfo()) ; } } |
3. 接口(interface)
3.1 接口的概念
接口是抽象方法与常量的结合.
接口的定义方式为: interface 接口名 { 数据类型 常量名 = 常量值; 返回值类型 方法名(); .......}
在Java中,一个类只能继承一个类,但是却可以实现(implements)多个接口. 如果实现接口的类不是抽象类的话,则该子类必须复写接口中所有的抽象方法.
例如如下代码示例:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | interface Person { //接口中包含了抽象类和抽象方法 public static final String NAME = "newsainton" ; public abstract void fun(); } // 一个类可以继承多个接口,但如果该类不是抽象类的话,则必须实现抽象类中的所有抽象方法 class Student implements Person { public void fun() { System.out.println( "name = " +NAME); } } public class Demo02 { public static void main(String args[]) { Student s = new Student(); s.fun(); } } |
3.2 接口的两点注意之处
(1). 抽象类使的是extends关键字,表示一个类只能继承一个父类,但是接口使用的是implements,一个类可以同时实现多个接口,但是此时子类就必须同时覆写好多个接口中的抽象方法。
(2). 既然定义中已经明确说明了接口是抽象方法和全局变量的集合,因此,我们可以如下例一样,对代码进行简化:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Student implements Person { public void fun() { System.out.println( "name = " +NAME); } } public class Demo03 { public static void main(String args[]) { Student s = new Student(); s.fun(); } } |
3.3 接口与接口之间的关系
一个接口可以使用extends关键字去继承一个或多个已有的接口,但在子类的实现时,也必须全部实现所有接口的抽象方法.
一个接口去继承并实现多个接口的例子如下:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | interface A { public void printA() ; } interface B { public void printB() ; } interface C extends A,B { public void printC() ; } class X implements C { // 如果实现了(继承)C接口,则在子类中就必须覆写全部的抽象方法 public void printA() { System.out.println( "A --> HELLO" ) ; } public void printB() { System.out.println( "B --> HELLO" ) ; } public void printC() { System.out.println( "C --> HELLO" ) ; } } public class Demo04 { public static void main(String args[]) { X x = new X() ; x.printA() ; x.printB() ; x.printC() ; } } |
3.4 这里,如果一个子类既要继承一个抽象类,又要实现一个接口,该怎么写呢?
我们采取的是: class 类名称 extends 抽象类 implements 接口 这样的语法格式.
下面是同时继承一个抽象类,又实现接口的具体实例:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | interface X { public void printX() ; } interface Z { public void printZ() ; } // 一个抽象类也是可以实现接口的 abstract class Y implements Z { public abstract void printY() ; } // D类同时继承Y类和实现X接口 class D extends Y implements X { public void printX() { System.out.println( "X --> HELLO ." ) ; } public void printY() { System.out.println( "Y --> HELLO ." ) ; } public void printZ() { System.out.println( "Z --> HELLO ." ) ; } } public class Demo13 { public static void main(String args[]) { D d = new D() ; d.printX() ; d.printY() ; d.printZ() ; } } |