你真的了解interface和内部类么

隐身守侯 提交于 2020-02-28 05:37:30

java 访问控制符


private     : 只能被当前类访问

protected : 可以被同包的类和任何子类访问(包内,包外)

default    : 可以被包内的任何内访问

public     : 任何类都可以访问

Java重载可以改变类的访问控制符么?

可以! 但只能将访问权限变大,不能缩小。比如

A extends B ,B中有一个M方法是 则M支持如下扩充:(private不支持重载)

default  —— protected

default  —— public

protected —— public

接口


接口是类么?

由下图可以看出,接口和类同属于java数据类型的引用数据类型,他们是同等级的,接口并不是类。类是用class定义,而接口是inteface定义。

b3119313b07eca8061c651e2972397dda04483f7

接口中可以定义成员变量么?

接口的含义理解:接口可以理解成统一的"协议",而接口中的属性也属于协议中的内容;但是接口的属性都是公共的,静态的,最终的

接口的成员特点
A:成员变量 只能是常量。默认修饰符 public static final
B:成员方法 只能是抽象方法。默认修饰符 public abstract

接口内的函数 需要 public,private,protected,abstract 修饰么?

如果我们在定义一个接口时,给内部的某个接口加上“public” 修饰符,不会报错,但是编译器会提示如下:

image

意思是“public” 修饰符是多余的。

那么我们加 private,protected会怎么样呢?

image

可以看出 接口的内部函数默认就是public的。

1. 如果接口方法是private 只有当前接口能访问,哪还有什么意义。

2. 如果是default或者protected : 因为接口谈不上子类只有implement关系,protected不能修饰。那能不能不加任何访问控制符呢?实际编译不加任何 控制符会自动变为public。(接口设计的初衷就是大家都能调用访问)

在接口前加 abstract字段:

image

和增加“public” 结果相同,接口内的函数默认就是抽象public函数,不需要增加 abstart public关键字

定义接口时 public,private,protected 含义?我们定义一个class会用这几种访问控制符修饰。

接口不能用 private  和 protected 修饰:

1、 private 接口只能自身访问自身,让接口失去了任何意义。

2、protected 修饰则表示只能被子类访问和同一个包内的其它类访问。protected比default多部分类可以访问:包外的子类。

那么对于接口来说,它没有任何子类,所以protected对它无效。

public接口和 default接口

default接口只能在包内写一个内去implement,包外则不能去implement。

内部接口


内部接口是定义在一个类的内部的接口。

内部接口的优点:

1.一种对那些在同一个地方使用的接口进行逻辑上分组;
2.封装思想的体现;
3.嵌套接口可以增强代码的易读性和可维护性;

在Java标准库中使用内部接口的一个例子是java.util.Map和Java.util.Map.Entry。这里java.util.Map同样被当成命名空间使用。Entry并不属于全局作用域范围.

内部接口需要加上static么

比如封装的一个Request类,用于请求后台的某个参数,那我们肯定需要设置一个监听器接口来监听请求的状态及返回的结果,设置结构如下:

public class Request {

    private ListenerInterface listener;

    static public interface ListenerInterface{
        void onResult();
    }

    public void request(){
        doResest();
        listener.onResult();
    }

    private void doResest(){

    }
}

其实定义在一个类内部的接口,默认就是static的,所以再加一个static关键字修饰是多余的。假如一个类接口可以定义成非static类型的,那么外部去实现这个接口之前必须要实例一个外部类的对象才能去实现该接口,上述代码中要初始化一个Request对象 Request requet = new Request(); 然后 new request.ListenerInterface(){ void onResut(){} } ,这样就不能做到接口和类的分割,不符合接口功能的独立性思想。

内部类


public class test {

    private Object []obj;
    private int next = 0 ;

    test(int i){
        obj = new Object[i];
    }

    public void addObject(Object j){
        obj[next++] = j;
    }

    int getLength(){
        return obj.length;
    }
    public class inerObject {
        private int i=0;
        public boolean end(){
            return i==obj.length;
        }
        public Object current(){
            if(i>=obj.length)
                return null;
            else
                return obj[i];
        }
        public Object next(){
            if(obj.length==0||i>=obj.length){
                System.out.print("i is : "+i+"");
                return null;
            }

            else {
                System.out.print("i is : "+i+"");
            }
                return obj[++i];
        }
    }


    public  static void main(String []args){
        test t = new test(10);
        for(int i=0;i<t.getLength();i++){
            t.addObject(Integer.toString(i));
        }
        inerObject ir = t.new inerObject();
        while(!ir.end()){
            System.out.println(ir.next());
        }
    }
}

在Main中构建 内部类时必须有一个 外部类的对象,否者不能实例化

         inerObject ir = t.new inerObject();1、因为构建内部类对象时,需要一个指向其外部类对象的引用,如果编译器访问不到这个引用时就会报错。(static除外)
2、由上述代码可知,内部类可以访问所在类的成员变量。

嵌套类

  如果不需要 内部类对象与外围对象之间有联系,那么可以将内部类声明为static,通常称为嵌套类。

嵌套类的作用:

  1、从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用(即是作为外围类的成员变量一样使用)。如果在外围类的作用域外使用该类名时,需要加名字限定。

       2、从访问权限的角度来看,嵌套类名与它的外围类的对象成员名具有相同的访问权限规则。不能访问嵌套类的对象中的私有成员函数,也不能对外围类的私有部分中的嵌套类建立对象。

匿名内部类


匿名内部类也就是没有名字的内部类正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写但使用匿名内部类还有个前提条件:

必须继承一个父类或实现一个接口

实例1:不使用匿名内部类来实现抽象方法
abstract class Person {
    public abstract void eat();
}

class Child extends Person { public void eat() { System.out.println("eat something"); } }
public class Demo {
    public static void main(String[] args) {
        Person p = new Child();
        p.eat();
    }
}

运行结果:eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用

但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?这个时候就引入了匿名内部类

 
实例2:匿名内部类的基本实现
abstract class Person {
    public abstract void eat();
}

public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!