HOME/Articles/

Java中的面向对象的简单介绍(五)包和修饰符以及内部类

Article Outline

Java中的面向对象的简单介绍(五)包和修饰符以及内部类

<!--more-->

###包 特点:

  • 可以有多层
  • 不同包下面的文件名可以重复
  • 包的声明必须要在第一行

不同包下的相互访问

相同包下的类可以直接访问,不需要其他的操作。

那么不同包下的类的相互访问的方式有:

  1. 使用类的全名(即包名+类名),举例:java.util.ArrayList list1 = new java.util.ArrayList();
  2. 使用关键字import直接把这个类名导入进来,举例:import java.util.ArrayList;

也可以写`import java.util.;`代表把这个包下的所有类都导入,但是并没有导入这个包的子包下的类*

权限修饰符

public default private protected

修饰符 当前类中的权限 相同包下不同类中权限 不同包下的权限
public 可以访问 可以访问 可以访问
default 可以访问 可以访问 不可以访问
private 可以访问 不可以访问 不可以访问
protected 可以访问 可以访问 不可以访问

这么一看default和protected的差别没体现出来

default是当前包下使用,而protected是让子类对象使用。(super.protectedMethod();)

修饰符

顺便总结一下所有的修饰符,true为可以修饰,false为不可以修饰

修饰符 成员变量 成员方法 构造方法
public true true true true
default true true true true
protected false true true true
private false true true true
abstract true false true false
static false true true false
final true true true false

###一般常见的规则:

  • 类: 一般使用public 修饰类,原则上一个java文件中只能有一个类,但是如果有多个类的话,类名和文件名相同的那个类,必须要用public修饰,并且其他类不可以使用public修饰
  • 成员变量: 一般使用private修饰,并且提供getXxx()和setXxx()供外部使用。

  • 成员方法: 一般方法都用public修饰,不想暴露出的话就用private,想让子类用就使用protected

  • 构造方法: 一般也使用public修饰,但是如果不想让当前类实例化,可以private构造函数。

内部类

在另外一个类的内部的类

分类:

  • 成员内部类
  • 局部内部类
  • 匿名内部类

内部类虽然在别的类的内部,但是编译时会有单独的class文件。

成员内部类:

public class InnerClass {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.method(); // Inner Function  3  

        // 如果想直接在外部调用Inner的对象调用方法的话  可以直接import 包名.Outer.Inner
        // 也可以直接写类的全名来创建对象
        Outer.Inner i = new Outer().new Inner();
        i.func(); // 这样就可以直接创建Inner的对象了
    }
}

class Outer {
    private int num = 3;
    public void method() {
        Inner i = new Inner();
        i.func();
    }
    class Inner { // 在类的内部定义的类  成员内部类  可以访问Outer类中的成员
        public void func() {
            System.out.println("Inner Function");
            System.out.println(num);
        }
    }
}

成员内部类的修饰符

关于成员内部类的修饰符,有几个特殊情况:

  • private,如果使用private修饰内部类,那么只能在当前类中访问,不可以在外部使用:
    public class InnerClass2 {
      public static void main(String[] args) {
           // Outer.Inner i = new Outer().new Inner(); //  由于Inner被private修饰 提示Outer.Inner不可见
      }
    }
    

class Outer { private int num = 3; public void method() { Inner i = new Inner(); i.func(); } private class Inner { // 使用private修饰了成员内部类之后 外部不可见 public void func() { System.out.println("Inner Function"); System.out.println(num); } } }

- static, 如果使用static修饰,那么不需要创建Outer类的实例就可以创建Inner的实例:

public class InnerClass2 { public static void main(String[] args) { Outer.Inner2 i = new Outer.Inner2(); // 由于Inner被static修饰 所以不用创建Outer的实例 直接new Outer.Inner2()就可以创建这个实例了 } }

class Outer { private int num = 3; public void method() { Inner i = new Inner(); i.func(); }

static class Inner2 {  // 使用static修饰了成员内部类之后  创建对象就不用创建Outer类的实例了。
    public void func() {
        System.out.println("Inner Function");
        System.out.println(num);
    }
}

}


当然也可以使用其他修饰符如abstract, final等修饰内部类,但是没什么太大的实际意义。


#### 局部内部类

局部内部类的使用较少,在成员方法内部定义类,在方法外部就不可用。

// 局部内部类 public class InnerClass3 { public static void main(String[] args) { Outer o = new Outer(); o.method(); // Inner Function } }

class Outer { private int num = 3; public void method() { class Inner { // 局部内部类 在方法内部定义 public void func() { System.out.println("Inner Function"); } }

    Inner i = new Inner(); // 先定义类后实例化
    i.func();
}

}

#### 匿名内部类

可以看做是一个没有名字的局部内部类,也是定义在方法当中。

必须要在定义匿名内部类的时候创建其对象。

原理是:创建了继承这个类的子类或者是实现了这个接口的子类的对象。

举例来说明:

// 匿名内部类 public class InnerClass4 { public static void main(String[] args) { Outer o = new Outer(); o.method(); // Inner Function } }

interface Inner { // 创建一个接口或者类 public abstract void func(); }

class Outer { public void method() { new Inner() { // 定义内部类 @Override public void func() { System.out.println("Inner Function"); } }.func(); // 可以直接调用方法,前面的就是一个实例对象了

    // 也可以这么写
    Inner i = new Inner() { // 由于实现了接口  可以向上转型
        @Override
        public void func() {
            System.out.println("Inner Function");
        }
    };
    i.func();
}

}