接口与内部类

1.接口

首先接口不是类,而是对类的一组需求描述。下面是泛型类型的接口代码

public interface Comparable<T>

{

int compareTo(T other);

}

接口中的所有方法自动属于public,在接口中声明方法,不必提关键字public。注意,接口中不能提供实例域和方法实现,这些必须由实现接口的那个类来完成。

这里简单举例说明下实例域的概念:

举个例子:人类是一个类,张三就是人类的一个实例。
人类都有手、脚,可以理解为 人类的域。
张三的手、脚就是张三这个实例的自己的私有的域,比如张三有一个手指是断的,不能说人类的手

这里接口和没有实例域的抽象类类似,但它们还是有所区别。有如下区别:

1.接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的。

2.接口可以实现多重继承,而一个类只能继承一个超类,但可以通过继承多个接口实现多重继承。

3.接口可以多继承,抽象类不行。

4.接口中基本数据类型为static 而抽类象不是的。

以下是实现接口方法的语句(注意:在现实接口时,必须把方法声明为public,否则,编译器将认为这个方法的访问属性是包可见性,即类的默认访问属性,之后编译器就会给出试图提供更弱的访问权限的警告信息):

class Employee implements Comparable<Employee>

{

public int compareTo(Employee other)

{

return Double.compare(salary,other.salary);

}

}

我们再来看接口的一些特性:

1.接口不是类,所以不能用x=new Comparable(...);来实例化一个接口,但可以先声明一个接口变量,再对其进行类的实例化。

Comparable x;

x=new Employee(...);

2.我们可以用一下语句来检查对象是否实现了某个特定的接口:

if(anObject instanceof Comparable){...}

3.接口也可以扩展

public interface Moveable

{

void move(double x,double y);

}

public interface Powered extends Moveable

{

doble milePerGallon();

}

public interface Powered extends Moveable{

double milesPerGllon();

double SPEED_LIMIT=95;//a public static final constant,接口中的域将被自动设为public static final.

2.内部类

定义在另一个类中的类,称为内部类。

1.内部类可以对同一个包中的其他类隐藏起来。 (一般的非内部类,是不允许有 private 与protected权限的,但内部类可以)

2.内部类方法可以访问外围类中定义所在作用域中的数据,包括私有的数据。

3.可以实现多重继承

4.可以避免修改接口而实现同一个类中两种同名方法的调用。

5.当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。

 内部类嵌套类的两个重要作用是:命名控制和访问控制

看下面这个C++嵌套类的例子:

Class LinkedList

{

public:

       class Iterator

{

public:

    void insret(int x);

    int erase();

     ...

};

private:

    class Link

{

public:

      Link*next;

      int data;

}

...

};

Iterator被嵌套在LinkedList类内部,我们可以用LinkedList::Iterator的方式命名来避免与其他名为Iterator的类重复。

即使Link的数据域被设计为公有的,它仍然安全,只能被LinkedList中的方法访问。

注意,JAVA中的内部类还有另外一个功能,内部类的对象有一个隐式引用,通过这个指针可以访问外围类对象的全部状态。请看下面的java内部类的例子:

public class TalkingClock

{

private int interval;

private boolean beep;

public TalkingClock(int interval,boolean beep){...}

public void start(){...}

public class TimePrinter implements ActionListerner

{

public void actionPerformed(ActionEvent event)

{

Date now=new Date();

System.out.println("At the tone,the time is"+now);

if(beep)Toolkit.getDefaultToolkit().beep();//我们把外围类对象的引用称为outer,所以该语句等价于if(outer.beep)Toolkit.getDefaultTookit().beep();

//使用外围类引用的正规语法还要复杂一些。表达式为:OuterClass.this,所该语句可以改写为if(TalkingClock.this.beep)Toolkit.getDefaultTookit().beep();

}

}

从上面的例子看出,内部类可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。注意可以用outerObject.new Inner(construction paramenters)

来编写内部对象的构造器。同样可以用OuterClass.InnerClass的语法来引用内部类。

我们继续来看下面这个局部内部类

public void start()//我们把该语句改成public void start(int interval,final boolean beep), 这样局部类不仅能访问它们的外部类,还可以访问局部变量,注意局部变量必须被

//声明为final,局部变量的访问非常容易,它减少了需要显示编写的实例域,从而使得内部类更加简单。

{

class TimePrinter implements ActionListener

{

public void actionPerformed(ActionEvent event)

{

Date now=new Date();

System.out.println("At the tone,the time is"+now);

if(beep) Toolkit.getDefaultTookit().beep();

}

}

ActionLister listener=new TimePrinter();

Time t=new Timer(interval,listener);

t.start();

}

注意局部类不能用public或者private访问说明符进行声明,它的作用域被限定在声明这个局部类的块中。因此,它有一个更大的优势是,对外部世界完全的隐藏起来,

除start方法之外,没有任何方法知道TimePrinter类的存在。

匿名内部类

创建这个类的一个对象,就不必命名了,我们称为匿名内部类。

public void start(int interval,final boolean beep)

{

ActionListener listener=new ActionListener()

{

public void actionPerformed(ActionEvent event)

{

Date now=new Date();

System.out.println("At the tone,the time is"+now);

if(beep)Toolkit.getDefaultToolkit().beep();

}

};

Timer t=new Timer(interval,listener);

t.start();

}

注意匿名类没有类名,而构造器的名字必须域类名相同,所以匿名类没有构造参数。

静态内部类

如果我们仅仅想把一个类隐藏在另一个类中,而不需要引用外部对象,可以将内部类声明为static,以便取消产生引用。

转载于:https://www.cnblogs.com/AKLS/p/5900679.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值