第十章
抽象类 、 接口 与内部类
10.1抽象类
10.1.1 抽象类引出
当一个父类的某一些方法需要声明,但是呢又不知道该如何去实现,一般都是子类去具体实现的,这时候就可以将其父类设置为抽象类。
例:有一个动物,有eat方法,但是具体怎么实现不知道
public class Abstract01 {
}
abstract class Animal{
private String name;
public abstract void eat();
}
1、abstract抽象类就是没有具体实现方法的方法
2、需要注意:在一个类中有abstract抽象方法的时候,则该类要设计为abstract类
10.1.2 抽象类介绍
1、用abstract关键字来修饰一个类时,这个类就叫抽象类 语法: 访问修饰符 abstract 类名{ }
2、用abstract关键字来修饰一个方法时,这个方法就是抽象方法 语法: 访问修饰符 abstract 返回类型 方法名 (参数列表); //注意:是没有方法体的
3、抽象类更多在于设计,是设计者设计好后,让子类继承并实现抽象类()
4、抽象类,是考官比较爱问的知识点,在框架和设计模式中使用较多
10.1.3 抽象类细节
1、抽象类不能被实例化
2、abstract抽象类不一定要包含abstract抽象方法,也可以有实现的方法
3、类里面有abstract抽象方法那么该类一定是abstract抽象类
4、abstract抽象只能去修饰类和方法,不能修饰属性和其他 5、抽象类可以有任意成员(因为抽象类的本质始终还是一个类),比如有:非抽象的方法、构造器、静态属性等等
6、抽象方法不能有主体 7、如果一个类继承了抽象类,那么它必须实现抽象类的所有抽象方法,除非它自己也声明为抽象类
8、抽象方法不能使用private、final 和 static 来修饰,因为这些关键字和重写是像制约的
10.1.4抽象类最佳实践----模板设计模式
例: 分别计算多个类中,完成不同任务所需要的时间, AA类 计算1+…+1000000所花的时间 BB类 计算1*…500000的时间
思路:在两个类中分别通过 结束时间-开始时间 去计算不同类完成某工作的时间
public class AA {
public static void main(String[] args) {
long start = System.currentTimeMillis();
long sum = 0;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("AA 所花的时间 "+(end - start));
}
}
public class BB {
public static void main(String[] args) {
long start = System.currentTimeMillis();
long sum = 0;
for (long i = 0; i < 500000; i++) {
sum *= i;
}
long end = System.currentTimeMillis();
System.out.println("BB 所花的时间 "+(end - start));
}
}
以上解法,可以看出方法比较繁琐,两个类中有共同的语句了,所以,我们可以通过将主要的计算方法单独包装成一个方法,然后再用的时候去调用即可,优化后代码:
public class AA {
public static void main(String[] args) {
long start = System.currentTimeMillis();
work();
long end = System.currentTimeMillis();
System.out.println("AA 所花的时间 "+(end - start));
}
public static void work(){
long sum = 0;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
}
}
public class BB {
public static void main(String[] args) {
long start = System.currentTimeMillis();
work();
long end = System.currentTimeMillis();
System.out.println("BB 所花的时间 "+(end - start));
}
public static void work(){
long sum = 0;
for (long i = 0; i < 500000; i++) {
sum *= i;
}
}
}
以上方法明显比第一个简单一点,但是还是比较繁琐,要是当要计算的类比较多的时候,这样写也是很繁琐的,所以,通过以上代码我们可以看出来,不同类的基本结构都是一样的,都是先获取开始时间,然后运行功能方法,运行完后获取结束的时间,然后用结束时间去 - 开始时间 ,这样就可以获得类完成功能的时间,所以,我们可以将具体的功能方法封装成一个abstract抽象方法,子类具体去实现,然后将时间具体时间也给封装成一个方法。 优化后的代码
public class AA extends Template {
public void work(){
long sum = 0;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
}
}
public class BB extends Template{
public void work(){
long sum = 0;
for (long i = 0; i < 500000; i++) {
sum *= i;
}
}
}
public abstract class Template {
public abstract void work();
public void calculateTime(){
long start = System.currentTimeMillis();
work();
long end = System.currentTimeMillis();
System.out.println("执行时间:"+(end - start));
}
}
public class Abstract04 {
public static void main(String[] args) {
new AA().calculateTime();
new BB().calculateTime();
}
}
10.2 接口
10.2.1 接口的基本介绍
接口(interface)就是给一些没有实现的方法,封装在一起,到某一个类要使用的时候,再根据实际情况去把这些方法写出来。
语法: interface 接口名{ //属性 //方法(1、抽象方法 2、默认实现方法(需要用default修饰) 3、静态方法) }
当一个类要去使用接口的时候 语法: class 类名 implement 接口名{ //自己的属性 //自己的方法 //注意:必须要实现接口的抽象方法 }
注意: 1、在 jdk7.0 前,接口里所有的方法都是抽象方法,也就是没有方法体的 2、在 jdk8.0 后,接口可以有静态方法、默认方法,也就是接口中可以有方法的具体实现
public interface Interface01 {
public int sum = 10;
public String name="acd";
public void cry();
default public void cry2(){
System.out.println("默认实现方法...");
}
public static void cry3(){
System.out.println("静态方法...");
}
}
public class Interface01Text implements Interface01{
@Override
public void cry() {
System.out.println("类实现接口cry1");
}
}
10.2.2接口的细节
1、接口不能被实例化
2、接口中,所有的方法都是 public,而且 public 已经是默认的了,所以也可以不写,接口中的抽象方法,也可以不用 abstract 去修饰 3、一个普通的类实现接口,就必须将该接口的所有方法都实现,主要是抽象方法必须实现,要是接口中有default 修饰的默认实现方法,或者static修饰的静态方法,则可以不用去实现(11.1中的代码可以深刻的体现) 如果需要实现的方法较多的时候,可以用快捷键(alt + enter)去一键补全 4、抽象类实现接口,可以不用实现接口的方法 5、一个类,可以实现多个接口,每一个接口的方法都必须要去实现,和上面细节3的要求一样 6、接口中的属性,只能是final的,修饰符是 public static final 去修饰的,并且必须要初始化 7、接口中属性的访问形式是: 接口名 . 属性名 8、接口不能继承其他的类,但是可以继承多个其他接口(接口与接口之间是 extends 继承,接口和类之间是 implement 实现)
注意:一个类要是继承了有父类的接口,那么这个类就必须要去实现这个接口本身以及所有父类的所有为实现的抽象方法 9、接口的修饰符,只能是 public 和 默认,这一点和类的修饰符是一样的
10.2.3接口练习
判断下面代码是否有语法错误,没有的话,输出什么?
public class InterfaceText01 {
public static void main(String[] args) {
BB bb = new BB();
System.out.println(bb.a);
System.out.println(Ainter.a);
System.out.println(BB.a);
}
}
interface Ainter{
int a = 20;
}
class BB implements Ainter{ }
解答:
package com.xioawang.interface_;
public class InterfaceText01 {
public static void main(String[] args) {
BB bb = new BB();
System.out.println(bb.a);
System.out.println(Ainter.a);
System.out.println(BB.a);
}
}
interface Ainter{
int a = 20;
}
class BB implements Ainter{ }
输出:
20
20
20
10.2.4实现接口和继承的区别
1、接口的实现,是对Java单继承机制的补充
例: 现在有一只小猴子、一只老猴子、一只鸟、一条鱼;小猴子是老猴子的子类,从生下来就继承了老猴子会爬树的行为,但是呢,小猴子要是想要会飞,那么就只能去找鸟去学习飞翔,相当于就是小猴子去实现鸟飞翔的行为,小猴子要是想学会游泳,就去找鱼学习,然后去实现鱼游泳的行为
package com.xioawang.interface_;
public class InterfaceVsExtends {
public static void main(String[] args) {
LittleMonkey littleMonkey = new LittleMonkey("江仔");
littleMonkey.climing();
littleMonkey.flying();
littleMonkey.swimming();
}
}
class Monkey{
private String name;
public Monkey(String name) {
this.name = name;
}
public void climing(){
System.out.println(name+" 会爬树...");
}
public String getName() {
return name;
}
}
interface Bird{
void flying();
}
interface Fish{
void swimming();
}
class LittleMonkey extends Monkey implements Bird,Fish{
public LittleMonkey(String name) {
super(name);
}
@Override
public void flying() {
System.out.println(getName()+" 会飞翔...");
}
@Override
public void swimming() {
System.out.println(getName()+" 会游泳...");
}
}
结论: 1、当子类继承父类了后,子类就自动拥有了父类的功能 2、如果子类还想要拥有其他的功能,那么可以用实现接口的方式去扩展 3、实现接口,是对 Java 单继承机制的一种补充
2、接口和继承解决的不同问题 继承的价值:解决代码的复用性和可维护性 接口的价值:设计好各种规范(方法),让其它类去实现这些方法,也就是接口更加灵活
3、接口比继承更加灵活 接口比继承更加灵活,继承是 is - a 的关系,而接口是 like - a 的关系,通俗来说就是,猫是一个动物,但是同时可以通过接口去实现,像人一样的动作行为
4、接口在一定程度上实现代码解耦 在接口规范性 + 动态绑定机制 的基础上去实现代码的解耦
10.2.5 接口的多态性
1、接口的多态参数
也就是,接口的引用可以指向实现了接口类的对象实例;
语法:
接口类名 接口变量名 = new 实现接口的类名();
public class InterfacePloyParameter {
public static void main(String[] args) {
DInterface cInter = new C();
cInter = new D();
BBB bbb = new CC();
bbb = new DD();
}
}
interface DInterface{}
class C implements DInterface{}
class D implements DInterface{}
class BBB{}
class CC extends BBB{}
class DD extends BBB{}
2、接口的多态数组
例: 在 Usb数组中,存放 Phone 和 Camera 对象,Phone类还有一个特有的方法call(),请遍历 Usb 数组,如果存放Phone对象,除了调用Usb 接口定义的方法外,还需要调用Phone的特有方法call()
public class InterfacePloyArr {
public static void main(String[] args) {
Usb [] usb = new Usb[3];
usb[0] = new Phone("华为");
usb[1] = new Phone("苹果");
usb[2] = new Camera("索尼");
for (int i = 0; i < usb.length; i++) {
System.out.print(usb[i].message());
if (usb[i] instanceof Phone) {
System.out.println(" "+((Phone) usb[i]).call());
}
}
}
}
interface Usb{
String message();
}
class Phone implements Usb{
private String name;
public Phone(String name) {
this.name = name;
}
public String call(){
return getName()+"正在打电话ing...";
}
public String getName() {
return name;
}
@Override
public String message() {
return "我是:"+getName()+"手机";
}
}
class Camera implements Usb{
private String name;
public Camera(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String message() {
return "我是: "+getName()+"相机";
}
}
3、接口的多态传递 也就是两个接口之间存在继承关系,实现子接口的类相当于也实现了父接口 代码解释如下:
package com.xioawang.interface_;
public class InterfacePloyPass {
public static void main(String[] args) {
Finterface finterface = new E();
Einterface einterface = new E();
Dinterface dinterface = new E();
}
}
interface Dinterface{}
interface Einterface{}
interface Finterface extends Einterface{}
class E implements Finterface{ }
上面代码中要特别注意这句:
10.3 内部类
10.3.1 四种内部类
内部类基本介绍:
一个类里面又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套内部类的类叫做外部类,内部类是类的第五大成员
【类的五大成员:属性、方法、构造器、代码块、内部类】
内部类特点:
内部类可以直接访问类的私有属性,同时可以体现类与类之间的包含关系
内部类基本语法:
class Outer { //外部类
class inner{ //内部类
}
}
class Other{//其他类
}
快速入门案例:
public class InnerClass01 {
public static void main(String[] args) {
}
}
class Outer{
private String name;
public void cry(){ }
public Outer(String name) {
this.name = name;
}
class Inner{
}
}
注:内部类一共有四种:
1、定义在外部类的局部位置上(比如在方法内)
①局部内部类
②匿名内部类(重点!!!!)
2、定义在外部类的成员位置上:
①成员内部类(没有static修饰)
②静态内部类(使用static修饰)
10.3.2 局部内部类
基本介绍:
局部内部类就是定义在外部类的局部位置上,比如在方法中(通常也是在方法中),并且有类名
说明:
1、可以直接访问外部类的所有成员方法,包括私有的成员方法
2、不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的。
但是可以用 final 修饰,因为局部变量也可以使用final
**3、作用域:仅仅只能在定义它的方法或者代码块中**
4、局部内部类可以直接访问外部类的成员
5、外部类 访问 局部内部类 的成员,访问方式:先创建对象,再访问(注意:必须要在作用域内)
注:只能在局部内部类所在的外部类的方法中去创建对象,并且是在类创建完了后,才能实例化对象
6、外部其他类 ---不能访问----》局部内部类 (因为 局部内部类的地位是一个局部变量,作用域也只能在其所在的方法或者代码块中)
7、如果外部类的成员 和 局部内部类的成员 重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用: 外部类名.this.成员
public class JuBuInnerClass {
public static void main(String[] args) {
Outer05 outer05 = new Outer05();
outer05.hi();
System.out.println("main方法中的 Outer05.this 的hashcode值= "+outer05);
}
}
class Outer05{
private int n1 = 1;
public void hi(){
class Inner05{
private int n1 = 2;
}
Inner05 inner05 = new Inner05();
System.out.println("n1 = "+n1+" 外部类的n1 = "+ Outer05.this.n1);
System.out.println("内部的 Outer05.this 的hashcode值= "+Outer05.this);
}
}
输出:
n1 = 1 外部类的n1 = 1
内部的 Outer05.this 的hashcode值= com.xioawang.InnerClass.Outer05@1b6d3586
main方法中的 Outer05.this 的hashcode值= com.xioawang.InnerClass.Outer05@1b6d3586
注:<外部类名.this.成员> 中 <外部类名.this> 的本质是一个对象,即 是哪个实例化对象调用了含有局部内部类的方法,就是那个
10.3.3匿名内部类
10.3.3.1匿名内部类介绍
解析: 1、本质是一个类 2、内部类 3、该类没有名字(不能自己写,jdk底层会给分配一个:外部类名 $1) 4、匿名内部类同时也是一个对象(因为jdk底层再创建一个匿名内部类的时候,就会立即去实例化一个对象)
说明: 1、匿名内部类是定义在外部类的局部位置的,比如在方法中,或者代码块中
基本语法: new 类 或 接口(参数列表){ 类体 }
10.3.3.2匿名内部类使用案例
案例:基于接口的匿名内部类
package com.xioawang.InnerClass;
public class AnonymousInnerClass {
public static void main(String[] args) {
A a = new A();
a.classCry();
}
}
class A{
public void classCry(){
Ia tiger = new Ia(){
@Override
public void InterCry() {
System.out.println("老虎叫...");
}
};
tiger.InterCry();
System.out.println("匿名内部类的名称:"+tiger.getClass());
}
}
interface Ia{
public void InterCry();
}
输出:
老虎叫...
匿名内部类的名称:class com.xioawang.InnerClass.A$1
总结: 相当于就是,一个对象只希望被用一次,但是呢,按照传统方法再去创建一个类去实现接口再实例化对象,就会觉得很代码繁琐,为了简化,就可以创建一个匿名内部类去实现接口,再代码的底层中,会有一个底层分配的类去实现这个接口,并且实例化一个对象,匿名内部类的方法体就是你所要实现的方法。同时,基于接口的时候,接口中任何一个方法,都必须要在匿名内部类中去实现。毕竟这个类要去实现这个接口。
案例:基于类的匿名内部类
public class AnonymousInnerClass {
public static void main(String[] args) {
A a = new A();
a.classCry();
}
}
class A{
public void classCry(){
B b = new B("Tom"){
@Override
public void test() {
System.out.println("匿名内部类 重写tset方法....");
}
};
b.test();
System.out.println("b对象的运行类型:"+b.getClass());
}
}
class B{
private String name;
public B(String name) {
System.out.println("所接收到的name:"+name);
}
public void test(){
}
}
输出:
所接收到的name:Tom
匿名内部类 重写tset方法....
b对象的运行类型:class com.xioawang.InnerClass.A$1
总结: 基于类的匿名内部类,需要i注意:有{ }的才是匿名内部类,没有{ }的不是匿名内部类,同时{ }的方法体是可以不需要去写或者是重写的,并且,再底层代码中,匿名内部类的实现是通过 extends 继承的,同时创建过后也会直接实例化传给所接收的对象,并且参数列表的值,会传递到构造器中去。
案例:基于抽象类的匿名内部类
public class AnonymousInnerClass {
public static void main(String[] args) {
A a = new A();
a.classCry();
}
}
class A{
public void classCry(){
C c = new C(){
@Override
void eat() {
System.out.println("抽象类的匿名内部类中的抽象方法必须要写");
}
};
c.eat();
}
}
abstract class C {
abstract void eat();
}
输出:
抽象类的匿名内部类中的抽象方法必须要写
总结: 和基本的 基于类的匿名内部类是一样的,最大的区别就是,基于抽象类的时候,抽象类的所有抽象方法都要去实现。
10.3.3.3匿名内部类细节
1、从匿名内部类的语法中可以看出,它既是一个类的定义,同时也是一个对象,所以调用匿名内部类的方法也是很多种:
① 创建一个类对象,再用对象名去调用方法,这时的匿名内部类就是类的定义
②直接通过匿名内部类去调用方法,这时,匿名内部类就是一个对象 2、匿名内部类可以访问外部类的所有成员属性,包括私有
3、不能添加访问修饰符,因为它的地位就是一个局部变量 4、作用域:匿名内部类也只能在方法或者代码块中,并且只能使用一次 5、<外部其他类> - - -不能访问—<匿名内部类>(因为 匿名内部类的地位是一个局部变量)
6、如果外部类和内部类的成员属性同名的时候,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以用(外部类名 . this . 成员属性)
10.3.3.4匿名内部类最佳实践
1、当匿名内部类做为实参直接传递的时候
package com.xioawang.InnerClass;
public class InnerClassExerise01 {
public static void main(String[] args) {
BB bb = new BB();
fi(bb);
fi(new Ib() {
@Override
public void show() {
System.out.println("匿名内部类...");
}
});
}
public static void fi(Ib ib){
ib.show();
}
}
interface Ib{
void show();
}
class BB implements Ib{
@Override
public void show() {
System.out.println("传统方法...");
}
}
总结: 使用传统的方法去做的时候,比较繁琐,得先创建一个类,类去实现接口及方法,然后创建类对象,当作实参去传递方法;而匿名内部类的本质也是一个类和对象,所以可以通过直接用匿名内部类去当作实参传递,前提是,这个类所使用的次数很少。
============================ 2、有一个铃声的接口Bell,里面有个ring方法;有一个手机类Cellphone,具有闹钟功能alarmclock,参数是Bell类型;测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起床…;再传入另一个匿名内部类(对象),打印:小伙伴上课…
package com.xioawang.InnerClass;
public class InnerClassExercise02 {
public static void main(String[] args) {
Cellphone cellphone = new Cellphone();
cellphone.alarmclock(new Bell() {
@Override
public void ring() {
System.out.println("懒猪起床..");
}
});
cellphone.alarmclock(new Bell() {
@Override
public void ring() {
System.out.println("小伙伴上课...");
}
});
}
}
interface Bell{
void ring();
}
class Cellphone{
public void alarmclock(Bell bell){
bell.ring();
}
}
输出:
懒猪起床..
小伙伴上课...
分析下代码: 前提:接口、类这些准备工作准备好后 1、题目要求测试手机类,所以我们先创建一个手机对象
2、其次要求每一个实参传入就输出相应的铃声,说明这个铃声是只用一次的,所以用匿名内部类即可,就不用再去将手机类去实现接口,因为实现接口的话,一定要把接口的方法给实现了,那么可以说这个方法就已经具体了,虽然后面可以重写,但是代码还是会有冗余
3、手机类的方法所需要传入的实参是接口对象,那么可以使用匿名内部类去实现,再匿名内部类中去重写接口的 ring()方法,在这个地方,ring方法的编译类型是 接口 Bell ,但是运行类型不是手机类,而是 内部类所在的外部类的 外部类名 $ 1,所以,输出的不可能再是手机类里面的 ring()方法,而是外部类里面的匿名内部类的 ring()方法
10.3.4 成员内部类
基本介绍: 成员内部类是定义在外部类的成员位置的,并且没有 static 修饰 说明: 1、成员内部类可以访问外部类的所有成员,包括私有的(因为成员内部类的位置就是外部类的成员,所以我们要去调用实现它的话,可以在外部类中写一个方法,然后在方法中去创建成员内部类的对象,再通过这个对象去调用成员内部类的方法、成员) 2、可以添加任意的访问修饰符(public、private、protected、默认),因为它的地位就是外部类的一个成员 3、作用域:和外部类的其他成员一样,在整个类体中可以使用;比如在前面案例中,在外部类的成员方法中创建成员内部类对象,再去调用方法。 4、成员内部类 可以直接访问 外部类 的所有成员,包括私有的 5、外部类 访问 成员内部类(先创建对象,再去访问) 6、外部其他类 可以访问 其他类,两种访问方式(既是:先创建一个外部类的对象,然后在外部类对象的基础上,再去创建一个成员内部类的对象)
public class MenberInnerClass01 {
public static void main(String[] args) {
Outer06 outer06 = new Outer06();
Outer06.Inner06 inner06 = outer06.new Inner06();
inner06.say();
Outer06.Inner06 inner061 = outer06.getInner06();
inner061.say();
}
}
class Outer06{
class Inner06{
public void say(){
}
}
public Inner06 getInner06(){
return new Inner06();
}
}
7、如果外部类和成员内部类的成员重名的时候,内部内访问的话,默认遵循就近原则。如果想访问外部类的成员,则使用 外部类名 . this. 成员名
public class MenberInnerClass01 {
public static void main(String[] args) {
Outer06 outer06 = new Outer06();
outer06.cry();
}
}
class Outer06{
private int n1 = 5;
class Inner06{
private int n1 = 10;
public void say(){
System.out.println("n1 = "+n1);
System.out.println("外部类的n1 = " + Outer06.this.n1);
}
}
public void cry(){
Inner06 inner06 = new Inner06();
inner06.say();
}
}
输出:
n1 = 10
外部类的n1 = 5
10.3.5 静态内部类
基本介绍: 静态内部类是定义在外部类的成员位置上,并且有 static 修饰
说明:
1、可以直接访问外部类的所有静态成员,包括私有的,但是不能直接访问非今天非静态成员 2、可以添加任意的访问修饰符(public、protected、private、默认),因为它本来就是一个成员 3、作用域:同其他成员,是整个类体 4、静态内部类 - - - -访问 - - - > 外部类(比如说:静态属性),直接访问即可,注意只能是静态的
5、外部类 - - - 访问- - - >静态内部类 访问方式:先创建对象,再访问 6、外部其他类 - - -访问- - -静态内部类
package com.xioawang.InnerClass;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import org.omg.CORBA.PRIVATE_MEMBER;
public class StaticInnerClass01 {
public static void main(String[] args) {
Outer07 outer07 = new Outer07();
Outer07.Inner07 inner07 = new Outer07.Inner07();
inner07.cry();
Outer07.Inner07 inner071 = outer07.getInner071();
inner071.cry();
Outer07.Inner07 inner072 = Outer07.getInner07();
inner072.cry();
}
}
class Outer07{
private int n1 = 10;
private static String name = "江仔";
private static void hi(){ }
static class Inner07{
private int sum = 1;
public void cry(){
System.out.println(name);
hi();
}
}
public static Inner07 getInner07(){
return new Inner07();
}
public Inner07 getInner071(){
return new Inner07();
}
public void ok(){
Inner07 inner07 = new Inner07();
inner07.cry();
}
}
输出:
江仔
江仔
江仔
7、如果外部类和静态内部类的成员重名时,静态内部类访问时,默认就近原则,要是要访问外部类成员,那么直接用:外部类名 . 成员,但是要确保成员属性是静态的 (这里不需要加 this 是因为本来就已经是static 修饰的静态成员了,加了this完全就没有意义)
package com.xioawang.InnerClass;
public class StaticInnerClass01 {
public static void main(String[] args) {
Outer07.Inner07 inner07 = new Outer07.Inner07();
inner07.cry();
}
}
class Outer07{
private static int n1 = 10;
static class Inner07{
private int n1 = 2;
public void cry(){
System.out.println("n1= "+n1+"外部类的n1= " + Outer07.n1);
}
}
}
输出:
n1= 2外部类的n1= 10
============================== 呀,到这里呢,我们的Java基础部分就全部学完了,这个过程呢,哈哈,怎么说呢,真的有点小乏味呀,知识点又多,后面要多多巩固呀,然后整装待发下个部分了~~~~
类、接口、内部类篇幅就在这结束了吖,这是整个Java学习中的第十章哦,觉得还不错的可以查看我完整的Java笔记哦: Java学习第二阶段(仍然在继续更新中~~~~) Java学习第一阶段
|