zoukankan      html  css  js  c++  java
  • 接口与内部类

    这个月已过去大半了,都没怎么学习Java。事情多也不能当做借口,按部就班地学习吧。

    接口中的所有方法自动地属于public。因此,在借口中声明方法时,不必提供关键字public。

    接口绝不能含有实例域,也不能在接口中实现方法。

    为了使用Arrays类的sort方法对Employee对象数组进行排序,Employee类就必须实现 Comparable接口。

    public interface Comparable<T>

    {

        int compareTo(T other);

    }

    在调用x.compareTo(y)的时候,x小于y,返回一个负数;x等于y返回0;否则返回一个正数。

    为了让类实现一个接口,通常需要下面两个步骤:

    1)将类声明为实现给定的接口; class Employee implements Compareble<Employee>

    2)对接口中的所有方法进行定义。

    public int compareTo(Employee other)

    {

        if(salary < other.salary) return -1;

        if(salary > other.salary) return 1;

        return 0;

    }

    接口不是类,不能使用new运算符实例化一个接口。然而,尽管不能构造接口对象,却能声明接口变量。

    Compareble x; //OK

    接口变量必须引用实现了接口的类的对象:

    x = new Employee(...);

    可以使用instanceof检查一个对象是否实现了某个特定的接口: if(anObject instanceof Compareble){...}

    接口也可以继承。

    public interface Moveable

    {

        void move(double x, double y);

    }

    public interface Powered extends Moveable

    {

        double milesPerGallon();

    }

    尽管在接口中不能包含实例域或静态方法,但是可以包含常量。例如:

    public interface Powered extends Moveable

    {

        double milesPerGallon();

        double SPEED_LIMIT = 95; // a public static final constant

    }

    尽管每个类只能够拥有一个超类,但却可以实现多个接口。这也就是抽象类和接口的使用区别。使用逗号将实现的各个接口分隔开。

    class Employee implements Cloneable, Comparable

    对象克隆

    对象变量只是标签,相互赋值只是让多个标签引用同一个对象而已。如果要创建一个对象的新拷贝,就要使用clone方法。

    clone是Object类的一个protected方法。它的默认操作是“浅拷贝”,即如果对象中包含了子对象的引用,那么拷贝的结果会使得两个域引用同一个子对象。

    对于每一个类,都必须做出下列判断:

    1)默认的clone方法是否满足要求。

    2)默认的clone方法是否能够通过调用可变子对象的clone得到修补。

    3)是否不应该使用clone。

    实际上,选项3是默认的。如果要选择1或2,类必须:

    1)实现Cloneable接口。

    2)使用public访问修饰符重新定义clone方法。

    由于默认的clone方法被声明为protected,因此无法直接调用anObject.clone(),必须重新定义clone方法,并将它声明为public。

    在这里,Cloneable并没有指定clone方法,这个方法是从Object类继承而来的。接口在这里只是作为一个标记,表明类设计者知道要进行克隆处理。如果一个对象需要克隆,而没有实现Cloneable接口,就会产生一个已检验异常。

    即使clone的默认实现(浅拷贝)能够满需求,也应该实现Cloneable接口,将clone重定义为public。

    class Employee implements Cloneable

    {

        public Employee clone() throws CloneNotSupportedException

        {

            return super.clone();

        }

    }

    下面是一个建立深拷贝clone方法的例子:

    class Employee implements Cloneable

    {

        public object Employee() throws CloneNotSupportedException

        {

            Employee cloned = (Employee)super.clone();

            cloned.hireDay = (Date)hireDay.clone();

            return cloned;

        }

    }

    内部类

    需要内部类的主要原因有以下三点:

    1)内部类的方法可以访问该类定义所在的作用域中的数据,包括私有的数据;

    2)内部类可以对同一个包中的其他类隐藏起来。

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

    C++中也有类的嵌套,有两个好处:命名控制和访问控制。

    由于类A嵌套在类B的内部,所以在外部被命名为B::A,这样就不会与其他名为A的类发生冲突。在Java中这个并不重要,因为Java包已经提供了相同的命名控制。

    需要注意的是,当类A位于类B的私有部分时,A对其他的代码均不可见,可以将A的数据域设计为共有的,它仍然是安全的。这些数据域只能被B类的方法访问,而不会暴露给其他的代码。

  • 相关阅读:
    Luogu-P1404 平均数
    树的直径与重心
    卡常技巧
    背包问题总结
    Codevs-1521 华丽的吊灯
    区间dp与环形dp
    Luogu-P1308 神经网络
    拓扑排序
    01分数规划
    Python学习 4day__基础知识
  • 原文地址:https://www.cnblogs.com/johnsblog/p/4109254.html
Copyright © 2011-2022 走看看