抽象類的定義與使用
抽象類的概念:
抽象類就是在普通類的基礎上擴充一些抽象方法,所謂的抽象方法指的是值聲明而未實現的方法(沒有方法體)
所有的抽象方法要求使用abstract關鍵字來定義,並且抽象等待所在的類也一定要用abstract關鍵字定義,表示抽象類
abstract class Person{//定義一個抽象類
private String name;//屬性
public String getName() {//普通方法
return name;
}
public void setName(String name) {
this.name = name;
}
//{}裏面的代碼爲方法體,所有抽象方法不包含方法體
public abstract void getPerson();//抽象方法
}
抽象類中包含抽象方法,而抽象方法不包含方法體,即沒有具體實現因此抽象類不能夠產生實例化對象
對於抽象類的使用原則
a.所有的抽象類必須有子類
b.抽象類的子類必須覆寫抽象類的所有抽象方法
c.抽象類的對象可以通過對象多態性利用子類爲其實例化
d.private 與 abstract 不能同時使用
abstract class Person{
private String name;//屬性
public String getName() {//普通方法
return name;
}
public void setName(String name) {
this.name = name;
}
//{}裏面的代碼爲方法體,所有抽象方法不包含方法體
public abstract void getPerson();//抽象方法
}
class Student extends Person{
@Override
public void getPerson() {//覆寫父類方法
System.out.println("我是子類覆寫後的對象");
}
}
public class Test{
public static void main(String[] args){
Person per = new Student();
per.getPerson();//調用子類覆寫的方法
}
}
抽象類的相關規定:
1、在抽象類中允許提供構造方法,並且子類遵循對象實例化對象。實例化子類時必須先調用父類構造方法
abstract class Person{
private String name;//屬性
public Person(){//構造方法
System.out.println("Person類的構造方法");
}
public String getName() {//普通方法
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void getInfo();//抽象方法
}
class Student extends Person{
public Student() {
super();//如果父類沒有無參構造必須super指出調用的具體父類構造方法
System.out.println("Student類的構造方法");
}
@Override
public void getInfo() { }//子類覆寫方法空實現
}
public class Test{
public static void main(String[] args){
new Student();//Person類的構造方法
// Student類的構造方法
}
}
對象實例化操作的核心步驟:
類加載 -> 類對象的開闢 -> 類對象屬性的初始化(構造方法)
2、抽象類中允許不定義抽象方法,但是此時抽象方法仍然無法直接創建實例化對象
abstract class Person{
public void print(){
System.out.println("Person類的普通方法");
}
}
public class Test{
public static void main(String[] args){
Person per = new Person();//會報錯,Person類是抽象的,無法實例化
}
}
3、抽象類一定不能使用final聲明,因爲final聲明的類不允許有子類,抽象類又必須有子類;抽象方法也不能用private定義,因爲抽象方法必須被覆寫
4、抽象類分爲內部抽象類和外部抽象類。內部抽象類中可以使用static定義來描述外部抽象類
abstract class Person{
public abstract void print();//外部類抽象方法
static abstract class Student{
public abstract void print2();//內部類抽象方法
}
}
class Child extends Person{
@Override
public void print() {
}
class A extends Student{
@Override
public void print2() {
}
}
}
接口的定義與使用
抽象類與普通類相比最大的特點就是約定了子類的實現要求,但是抽象類存在單繼承侷限,如果要約定子類的實現要求且避免單繼承就可以使用接口
接口的基本概念
定義:接口就是一個抽象方法和全局常量的集合,用interface關鍵字定義
interface Imes{
public static final String MSG = "這是一個全局常量";
public abstract void print();//抽象方法
}
子類要想實現接口,就必須使用implements關鍵字來實現接口。
同時,一個子類可以實現多個接口,對於接口的子類必須覆寫接口的全部抽象方法,隨後利用子類的向上轉型通過實例化子類得到接口的實例化對象
子類實現接口 & 父接口相互轉換
interface Imes{
public static final String MSG = "這是一個全局常量";
public abstract void print();//抽象方法
}
interface INew{
public abstract String getNews();
}
class Mess implements Imes,INew {
@Override
public void print() {
System.out.println(Imes.MSG);
}
@Override
public String getNews() {
return Imes.MSG;
}
}
public class Test{
public static void main(String[] args){
Imes m = new Mess();//子類實現向上轉型
//真正new的子類纔有意義
m.print();//調用被子類覆寫過的方法
INew n = (INew) m;
System.out.println(n.getNews());
}
}
接口使用限制
接口只允許使用public權限(不管是屬性還是方法,其權限都是public)
接口的兩種定義:
//完整格式:
interface Imes{
public static final String MSG = "這是一個全局常量";
public abstract void print();
}
//簡化格式:
interface Imes{
final String MSG = "這是一個全局常量";
void print();
}
阿里編碼規約:接口中的方法和屬性不加任何修飾符號,public也不要加,保持代碼的簡潔性
當一個子類即需要實現接口又需要繼承類時,需先使用extends繼承一個抽象類,而後使用implements實現多個接口
//子類繼承抽象類和實現接口
abstract class News{
//抽象類中方法前面的abstract不能省略,否則就是普通方法
public abstract void getNews();
}
class Message extends News implements Imes{
@Override
public void print() {
System.out.println("我覆寫了接口方法");
}
@Override
public void getNews() {
System.out.println("我覆寫了抽象方法");
}
}
public class Test{
public static void main(String[] args){
//Message是抽象類與接口的共同子類
Imes m = new Message();
m.print();
News news = (News) m;
news.getNews();
}
}
一個抽象類可以使用implements實現多個接口
interface Imes{
void print();
}
abstract class News implements Imes{
//抽象類中方法前面的abstract不能省略,否則就是普通方法
public abstract void getNews();
}
class Message extends News{
@Override
public void print() {
System.out.println("我實現了接口方法");
}
@Override
public void getNews() {
System.out.println("我實現了抽象方法");
}
}
此關係屬於三層繼承
class Message extends News implements Imes
一個接口可以使用extends繼承多個父接口
interface A{
void printA();
}
interface B{
void printB();
}
interface C extends A,B{
void printC();
}
class Impl implements C{
@Override
public void printA() { }
@Override
public void printB() { }
@Override
public void printC() { }
}
接口可以定義一系列的內部結構,包括:內部普通類、內部接口。其中使用static定義的內部接口就相當於一個外部接口
//使用static定義的內部接口
interface A{
void printA();
static interface B{
void printB();
}
}
class Impl implements A.B {
@Override
public void printB() { }
}
接口能力的應用:定義標準
接口在實際開發中有三大核心應用環境
a.定義操作標準
b.表示能力
c.在分佈式開發之中暴露遠程服務方法