接口和內部類
一.抽象類和抽象方法
abstract void f();
上面爲抽象方法採用的語法。
包含一個或者多個抽象方法的類必須限定爲抽象類。抽象類語法如下:
abstract class interface{……}
抽象類無法直接產生對象。抽象類可以不包含抽象方法。
如果從一個抽象類繼承,並想創建該新類的對象,就必須爲抽象類中的所有方法提供定義。
如果不提供定義,那麼導出類也是抽象類,且編譯器會要求用abstract來限定這個類。
二.接口
interface
關鍵字產生一個完全抽象的類,不提供任何具體實現。可以定義類中方法的方法名、參數列表、返回值類型,但是不能有任何方法體。
interface
前若不添加public
關鍵字,則只有包訪問權限。
接口中的方法即使不顯式聲明也是public
的。
接口中的域是隱式的static
和final
的。
下面是接口的語法:
interface Instrument {
int VALUE = 5;//static and final
void play(Note n);//Automatically public
void adjust();
}
下面是繼承接口的語法:
class Wind implements Instrument {
public void play(Note n) { … }//這裏必須是public void的
public void adjust() { … }
}
三.多重繼承
一個類同時繼承一個類和多個接口,也可以向上轉型成多個基類的語法:
interface CanFight {
void fight();
}
interface CanSwim {
void swim();
}
interface CanFly {
void fly();
}
class ActionCharacter {
public void fight() {}
}
class Hero extends ActionCharacter //先說明繼承的具體類
implements CanFight, CanSwim, CanFly {//再說明繼承的接口
public void swim() {}//由於fight方法體AC類中已有說明,所以不必再給出方法體
public void fly() {}
}
接口繼承接口的語法:用extends
關鍵字擴展接口中的語法
interface Monster {
void menace();
}
interface DangerousMonster extends Monster {
void destroy();
}
四.內部類
- 創建內部類的理由:
1.實現了某類型的接口,於是創建並返回對該接口的引用
2.想創建一個非公共類
- 內部類與外圍類的區別:
1.訪問權限
普通的類的關鍵字:public
或是默認
內部類的關鍵字還可以有:private
和protected
2.定義和引用的方式
外部類中一般有一個方法,該方法返回一個指向內部類的引用。
內部類定義、引用的,以及內部類生成對外部類引用的語法如下:
public class Parcel2 {
class Contents {//定義內部類
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
public Parcel2 outer() {
return new Parcel2.this;//內部類中返回對外部類的引用
}
}
public Destination to(String s) {
return new Destination(s);
}
public Contents contents() {
return new Contents();
}
public void ship() {}
public static void main(String[] args) {
Parcel2 p = new Parcel2();
Parcel2.Contents c = p.contents();//調用外部對象的方法產生內部類對象
Parcel2.Destination d = p.to("Beijing");//注意外部類.內部類的格式
d.outer().ship();//內部類生成對外部類的引用後調用方法
}
}
內部類和外部類一樣具有繼承的功能,並且內部類可以訪問外部類的任何成員。
- 向上轉型爲接口
內部類可向上轉型爲接口。該內部類(某個接口的實現)對外隱藏,得到的只是指向接口的引用。
向上轉型示例如下:
interface Destination {
String readLabel();
}
interface Contents {
int value();
}
public class Parcel3 {
private class PContents implements Contents {
public int value() {}
}
private class PDestination implements PDestination {
public String readLabel() {}
}
//引用內部類的方法Contents和to省略
public static void main(Sting[] args) {
Parcel3 q = new Parcel3();
Contents a = q.Contents();//內部類向上轉型爲接口
Destination b = q.to();
}
}
- 內部類的作用範圍
在某個方法或者某個作用域中定義的內部類,只在這個作用域中有效,不會與外部發生衝突。
內部類可以在方法中被定義,通過方法的返回值返回對內部類的引用,然後向上轉型爲接口。
- 匿名類:
public class Parcel6 {
public Contents cont() {
return new Contents() {
//創建一個繼承自Contents的匿名類的對象
private int i = 11;
public int value() { return i; }//必須public
};//這裏需要分號
}
}
上面的程序等同於
public class Parcel6{
class MyContents implements Contents {
private int i = 11;
public int value() { return i; }
}
public Contents contents() { return new MyContents(); }
}
如果定義一個使用外部變量的匿名類,這個外部變量必須是final
的。
語法如下:
public class Parcel8 {
public Destination dest(final String dest) {//final關鍵字
return new Destination() {
private String label = dest;//在匿名類中使用
public String readLabel() { return label; }
};
}
匿名類不能有構造器,所以需要對變量進行實例初始化。
- 與外部類進行鏈接
1.通過.this
在內部類中返回外部類的引用
2.通過.new
爲某些外部類創建內部類對象
class Text{
public class Inner {
void hhh() {
System.out.println("hhh");
}
}
}
public class Test {
public static void main(String[] args){
Text a = new Text();
Text.Inner b = a.new Inner();
b.hhh();
}
}//只有內部類及其構造器都是public時,才能夠Text.Inner以及調用Inner()
- 嵌套類、靜態內部類
將內部類聲明爲static
將成爲嵌套類。
要創建嵌套類的對象,不需要外圍類的對象。
不能從嵌套類的對象中訪問非靜態的外圍類對象。
public class Parcel10 {
private static class PContents implements Contents {…}//4個static
protected static class PDestination implements PDestination {…}
public static Destination dest(String s) {
return new PDestination(s);
}
//方法中public代表可以在包及包之外調用此方法,static使得可以直接調該方法生成內部類對象,而不需要內 //部類.外部類來鏈接
public static Contents cont() {
return new PContents();
}
public static void main(String[] args) {
Contents c = cont();//無需通過外部類來調用方法
Destination d = dest("1!");
}
}