一、内部类
1.1、内部类概念
定义在一个类内部中的另一个类,被称为内部类
特点:
可以直接访问,内部类的外部类中的,成员属性和方法(包含-private)
外部类要访问内部类中的成员和方法,需要先建立内部类对象
1.2、示例
package com.day08.innerclass.demo1;/** * 包含内部类 * @author denny * */public class Outer { //外部类 //private成员 private String name="张三"; private int age=20; private String gender="男"; /** * 内部类 */ class Inner{ private int num=3; public void hello(){ System.out.println("姓名:"+name+"年龄:"+age +"性别:"+gender); } public int getNum() { return num; } public void setNum(int num) { this.num = num; } } /* * 外部类中的方法 */ public void show(){ System.out.println("姓名:"+this.name+"年龄:"+this.age +"性别:"+this.gender); } /* * 调用内部类 */ public void say(){ Inner inner=new Inner(); System.out.println("调用内部类:"+"num="+inner.getNum()+", num="+inner.num); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
测试外部类
package com.day08.innerclass.demo1;public class OuterTest { public static void main(String[] args) { //外部类调用内部类 Outer o=new Outer(); o.show(); o.say(); }}
结果:
姓名:张三年龄:20性别:男
调用内部类:num=3, num=3
测试内部类
package com.day08.innerclass.demo1;public class InnerTest1 { public static void main(String[] args) { // 声明内部类中对 象,先声明外部类,再声明内部类 Outer.Inner inner = new Outer().new Inner(); inner.hello(); }}
姓名:张三年龄:20性别:男
调用内部类:num=3, num=3
1.3、静态内部类
如果内部类是static修饰的就只能调用父类中static成员
声明方式,可直接外部类.内部类()来声明或者调用
package com.day08.innerclass.demo3;public class Outer { //private成员 private String name="张三"; static int age=20; private String gender="男"; /* * 外部类中的方法 */ public void show(){ System.out.println("姓名:"+this.name+"年龄:"+this.age +"性别:"+this.gender); } /** * 内部类 */ static class Inner{ private int num=3; public void hello(){ System.out.println("外部类年龄:"+age +",内部类属性"+this.num); } } public static void main(String[] args) { //静态内部类可以直接通过外部类.内部类声明 Outer.Inner inner=new Outer.Inner(); inner.hello(); }}
外部类年龄:20,内部类属性3
1.4、内部类成员是static的话
这个内部类必须被static修饰,static只能调用外部类和内部类中的stiatic的成员.
package com.day08.innerclass.demo3;public class Outer { //private成员 private String name="张三"; static int age=20; private String gender="男"; /* * 外部类中的方法 */ public void show(){ System.out.println("姓名:"+this.name+"年龄:"+this.age +"性别:"+this.gender); } /** * 内部类 */ static class Inner{ private static int num=3; public static void hello(){ System.out.println("外部类年龄:"+age +",内部类属性"+num); } } public static void main(String[] args) { //静态内部类m成员也是静态的可以直接调用 Outer.Inner.hello(); }}
结果:外部类年龄:20,内部类属性3
1.5、声明在外部类中成员方法中的内部类
声明成员方法中的,内部类,调用成员方法中的局部变量 时,成员方法中的局部变量 必须为final修饰
package com.day08.innerclass.demo3;public class Outer { // private成员 private String name = "张三"; static int age = 20; private String gender = "男"; /* * 外部类中的方法 */ public void show(int x) { final int y = 5; //System.out.println("姓名:" + this.name + "年龄:" + this.age + "性别:" + this.gender); class Inner { public void hello() { System.out.println("hello-------"+x + " ," + y); } } Inner inner = new Inner(); inner.hello(); } /** * 内部类 */ public static void main(String[] args) { //声明成员方法中的,内部类,调用成员方法中的局部变量 时,成员方法中的局部变量 必须为final修饰 new Outer().show(8); }}
hello-------8 ,5
1.6、为什么内部类能直接访问外部类中的成员呢?
因为内部类持有了外部类的引用,外部类名.this。 (默认省略)
package com.day08.innerclass.demo4;public class Outer { private int num=3; class Inner{ private int num=4; public void show(){ int num=5; //局部变量 System.out.println(num); //内部类的成员变量 System.out.println(this.num); //外部类的成员变量 System.out.println(Outer.this.num); } } public static void main(String [] args){ new Outer().new Inner().show(); }}
二、匿名内部类
2.1、匿名内部类概念
内部类可以继承或实现一个外部类或者接口。
格式:
new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}
简单理解:
就是建立一个带内容的外部类或者接口的子类匿名对象。
什么时候使用匿名内部类呢?
通常使用方法是接口类型参数,并且该接口中的方法不超过三个,可以将匿名内部类作为参数传递。
好处:
增强阅读性。
2.2、重写类中的方法
package com.day08.innerclass.demo5;/** * 抽象类 * @author denny * */public abstract class Person { private String name="张三"; public void show(){ System.out.println(this.name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.day08.innerclass.demo5;/** * 外部类 * * @author denny 实现有一个方法的抽象类的匿名内部类 * */public class Outer { private int num = 3; public void say() { new Person() {// 匿名内部类 public void show() { //重写抽象类中的方法,抽象方法,普通方法都可以 System.out.println("..............." + num); } }.show(); //对象创建完成,调用自己 } public static void main(String[] args) { new Outer().say(); }}
结果:
...............3
第二种写法,适后重写了多个方法
package com.day08.innerclass.demo5;/** * 外部类 * * @author denny 实现有一个方法的抽象类的匿名内部类 * */public class Outer { private int num = 3; public void say() { Person person=new Person() {// 匿名内部类 public void show() { //重写抽象类中的方法,抽象方法,普通方法都可以 System.out.println("..............." + num); } }; //对象创建完成 person.show(); } public static void main(String[] args) { new Outer().say(); }}
2.3、示例使用接口的方式
package com.day08.innerclass.demo6;/** * 接口 * @author denny * */public interface BirdPro { /** * 2个抽象方法 */ public void shout(); public void accact();}package com.day08.innerclass.demo6;public class Outer { private String name="张三"; public void show(){ int y=3; BirdPro birdPro=new BirdPro(){ //实现接口中的方法 @Override public void shout() { System.out.println(name+","+y); } @Override public void accact() { System.out.println(y+","+name); } }; birdPro.shout(); birdPro.accact(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public static void main(String[] args) { new Outer().show(); }}
结果:
张三,3
3,张三
2.4、把匿名内部类做参数传递
- 通常的使用场景之一:
- 当函数参数是接口类型时,而且接口中的方法不超过三个。
- 可以用匿名内部类作为实际参数进行传递。
package com.day08.innerclass.demo6;/** * 接口 * * @author denny * */public interface BirdPro { /** * 2个抽象方法 */ public void shout(); public void accact();}
package com.day08.innerclass.demo6;class InnerDemo { public static void main(String[] args) { // 把接口做参数传递 show(new BirdPro() { // 实现接口中的方法 @Override public void shout() { System.out.println("叫声"); } @Override public void accact() { System.out.println("攻击"); } }); } public static void show(BirdPro birdPro) {// 做参数 // 调用 birdPro.accact(); birdPro.shout(); }}
2.5、 初始化顺序
package com.day08.innerclass.demo2;public class Fu { int num = 9; static{ System.out.println(" static Fu"); } { System.out.println("Fu"); } Fu() { super();// Object // 显示初始化 // 构造代码块初始化 show(); // 构造函数调用方法,如果子类已经重写了,父类的方法,则执行子类的方法,但这时,成员还没有初初始化,所以为默认值 } void show() { System.out.println("fu show " + num);// 被覆盖,运行子类的 }}
package com.day08.innerclass.demo2;public class Zi extends Fu { int num = 8; static{ System.out.println(" static Zi"); } { System.out.println("Zi" ); } Zi(){ super(); //显示初始化 //构造代码块初始化 show(); } void show(){ System.out.println("zi show " + num); }}
package com.day08.innerclass.demo2;public class Test1 { public static void main(String[] args) { new Zi(); }}
结果:
static Fu static ZiFuzi show 0Zizi show 8
原标题:基础学习day09
关键词: