接口和内部类
一.抽象类和抽象方法
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!");
}
}