JavaSE学习(七)面向对象-权限修饰符、匿名内部类

作者 Zhendong Ho 日期 2019-02-25
JavaSE学习(七)面向对象-权限修饰符、匿名内部类

package关键字

概述

包就是文件夹,可以将字节码进行分类存放。

包的定义

格式:package 包名;

多级包用.分开即可。

package com.zhdaa;
class Demo1_Package {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

注意

  • package语句必须是程序的第一条可执行的代码。
  • package语句在一个java文件中只能有一个。
  • 如果没有package,默认表示无包名。

带包的类编译和运行

编译:javac编译的时候带上-d参数。javac -d . Demo1_Package.java

运行:通过java命令执行。java 包名.类名

不同包下类之间的访问

package com.zhdaa;
class Demo1_Package {
public static void main(String[] args) {
com.baidu.Person p = new com.baidu.Person("张三", 23);
System.out.println(p.getName() + "..." + p.getAge());
}
}

import关键字

让有包的类对调用者可见,不用写类的全名。

格式:import 包名;

package com.zhdaa;
import com.baidu.Person;
import java.util.Scanner; //在开发中都是导入具体的类
//import java.util.*; //也可以写成通配符

class Demo1_Package {
public static void main(String[] args) {
Person p = new Person("张三", 23);
System.out.println(p.getName() + "..." + p.getAge());

Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
System.out.println(x);
}
}

注意:package、import和class有先后顺序。先是package(只能写一个),再来是import(多个),最后是class。

权限修饰符

四种访问修饰符

修饰符 本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y

内部类

内部类的特点

  • 内部类可以直接访问外部类的成员,包括私有。
  • 外部类要访问内部类的成员,必须创建对象。
  • 外部类名.内部类名 对象名 = 外部类对象.内部对象;。
class Demo1_InnerClass {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner(); //创建内部类对象
oi.method();
}
}

class Outer {
private int num = 10;
class Inner {
public void method() {
System.out.println(num); //内部类可以访问内部类的私有成员
}
}
}

成员内部类私有使用

当成员内部类是私有的时候,通过方法调用。

class Demo2_InnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.print();
}
}

class Outer {
private int num = 10;
private class Inner {
public void method() {
System.out.println(num);
}
}

public void print() {
Inner i = new Inner();
i.method();
}
}

静态成员内部类

class Demo1_InnerClass {
public static void main(String[] args) {
Outer.Inner oi = new Outer.Inner();
oi.method(); //method

Outer.Inner2.print(); //print
}
}

class Outer {
static class Inner {
public void method() {
System.out.println("method");
}
}

static class Inner2 {
public static void print() {
System.out.println("print");
}
}
}

成员内部类练习

使用已知的变量,输出30、20、10。

class Test1_InnerClass {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();//30 20 10
}
}

class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
}

注意:内部类之所以能获取到外部类的成员,是因为他能获取到外部类的引用,外部类名.this。

局部内部类

在方法中定义的类,叫做局部内部类。

class Demo1_InnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.method(); //Hello world!
}
}

//局部内部类
class Outer {
public void method() {
final int num = 10;
class Inner {
public void print() {
System.out.println(num);//在内部类中访问本地变量,需要声明为final类型
}
}

Inner i = new Inner();
i.print();
}

/*public void run() { //错误,局部内部类,只能在其所在的方法中访问
Inner i = new Inner();
i.print();
}*/
}

匿名内部类

匿名内部类就是内部类的简化写法。

前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类。

本质:是一个继承了该类或者实现了该接口的子类匿名对象。

class Demo1_NoNameInnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
interface Inter {
public void print();
}

class Outer {
class Inner implements Inter {
public void print() {
System.out.println("print");
}
}

public void method() {
//Inner i = new Inner();
//i.print();

new Inter() { //实现Inter接口
public void print() { //重写抽象方法
System.out.println("print");
}
}.print(); //Inter的子对象调用print方法,相当于new Inter().print();
}
}

匿名内部类重写多个方法调用

匿名内部类只针对重写一个方法时使用。

class Demo2_NoNameInnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.
}
}

interface Inter {
public void show1();
public void show2();
}
//匿名内部类只针对重写一个方法时使用
class Outer {
public void method() {
Inter i = new Inter() {
public void show1() {
System.out.println("show1");
}

public void show2() {
System.out.println("show2");
}

/*public void show3() {
System.out.println("show3");
}*/
};

i.show1();
i.show2();
//i.show3(); //匿名内部类不能向下转型,因为没有子类类名。
}
}

匿名内部类在开发中的应用

匿名内部类当作参数传递。

class Test1_NoNameInnerClass {
public static void main(String[] args) {
//如何调用PersonDemo中的method方法
PersonDemo pd = new PersonDemo();
pd.method(new Person() { //匿名内部类当作参数传递(本质把匿名内部类看作一个对象)
public void show() {
System.out.println("show");
}
});
}
}

//抽象类或者接口
abstract class Person {
public abstract void show();
}

class PersonDemo {
public void method(Person p) {
p.show();
}
}