案例:一个java文件里面是Demo1_Package类
package com.heima;
class Demo1_Package {
public static void main(String[] args) {
//Person p = new Person(); //报错:不同包下的类不能直接访问
com.baidu.Person p = new com.baidu.Person(); //类的全路径名
}
}
下面是另一个java文件里面是 Person类
package com.baidu;
class Person {
String name;
int age;
}
案例:一个java文件里面是Demo1_Package类
package com.heima;
import com.baidu.Person; //导包
class Demo1_Package {
public static void main(String[] args) {
Person p = new Person(); //导包后,就能直接访问了
}
}
另一个java文件里面是 Person类
package com.baidu;
class Person {
String name;
int age;
}
修饰符(☆☆)
权限修饰符的访问权限(☆☆☆☆)
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
代码:
class Demo1_InnerClass {
public static void main(String[] args) {
//Inner i = new Inner(); //报错,因为内部类是写在其他类的内部 不能这样直接创建内部类的对象
//i.method();
Outer.Inner oi = new Outer().new Inner(); //创建内部类对象 格式 :外部类名.内部类名 = 外部类对象.内部类对象
oi.method();
}
}
class Outer {
private int num = 10; //外部类的私有属性
class Inner {
String name = "内部类";
public void method() {
System.out.println(num); //内部类访问外部类的内容, 直接访问 包括私有
}
}
public void show(){
//System.out.println(name); //报错:外部类不能直接访问内部类的内容
Inner i = new Inner();
System.out.println(i.name); //这样才是正确的 外部类访问内部类里面的内容 ,必须创建内部类的对象来访问
}
}
成员私有内部类(☆):
class Demo2_InnerClass {
public static void main(String[] args) {
//Outer.Inner oi = new Outer().new Inner();//不能创建私有内部类的对象 因为内部类被私有了
//oi.method();
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();
Outer.Inner2.print(); //直接访问静态内部类里面的静态方法
}
}
class Outer {
static class Inner { //静态成员内部类
public void method() {
System.out.println("method");
}
}
static class Inner2 { //静态成员内部类
public static void print() { //静态方法
System.out.println("print");
}
}
}
内部类对象如何能访问当前外部类对象的成员变量?(☆)
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); //访问的是局部变量 30
System.out.println(this.num); //访问的是成员变量 20
System.out.println(Outer.this.num);//外部类名.this 访问的是当前外部类对象的num 10 (请注意这里是"当前外部类对象" ,如果不明白什么是"当前外部类对象"请看下面的案例)
}
}
}
这样类型的题的变形
class Test1_InnerClass {
public static void main(String[] args) {
Outer ot = new Outer();
ot.num = ot.num - 5;
Outer.Inner oi = ot.new Inner();
oi.show();
}
}
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num); //访问的是局部变量 30
System.out.println(this.num); //访问的是成员变量 20
System.out.println(Outer.this.num); //外部类名.this 访问的是当前外部类对象的num 5(因为 当前外部类对象ot的num值已经改变成了5 ot.num = ot.num - 5;)
System.out.println(new Outer().num); //一个新的外部类对象的num 10
}
}
}
class Demo1_InnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
class Outer {
public void method() {
final int num = 10;
class Inner {
public void print() {
System.out.println(num);
}
}
Inner i = new Inner(); //对象的生命周期比局部变量长,
i.print(); //当method()方法执行完毕后,i还存在着 就会导致 如果i对象还想访问num ,而num已经消失了,访问不到了。所以在num前面加final 永远放到常量池里面去,常量池的东西 永远都不会消失(虚拟机挂掉才会消失)
}
/*public void run() {
Inner i = new Inner(); //局部内部类,只能在其所在的方法中访问
i.print();
}*/
}
以上代码的变形体如下(此代码和day15将要学习的迭代器的源码有些类似):
class Demo1_InnerClass {
public static void main(String[] args) {
Outer o = new Outer();
Iff i = o.method(); //用父类的引用来接收 method()方法的返回值
//method()方法执行完毕后 method()内部的num如果不加final的话 就消失了 那下面的i.print()就不能再使用num了,所以num前面必须加上final修饰
i.print(); //对象调方法
}
}
interface Iff
{
public abstract void print();
}
class Outer {
public Iff method() { //此方法 返回值 是一个Iff 接口,所以该方法必须要返回一个Iff的子类对象
final int num = 10;
class Inner implements Iff{
public void print() {
System.out.println(num);
}
}
Iff i = new Inner(); //父类引用指向子类对象
return i; //返回一个 Iff的子类对象
}
}
匿名内部类(☆☆):
前提:有一个接口或者抽象类 或者 普通的类
格式(☆☆☆☆☆):
new 接口名或者抽象类名(){
重写方法;
};
本质(☆☆☆☆☆):就是接口或者抽象类或者普通类的一个子类对象