Java学习(十六)成员内部类,静态内部类,匿名内部类,局部内部类
Posted 泊而至远
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习(十六)成员内部类,静态内部类,匿名内部类,局部内部类相关的知识,希望对你有一定的参考价值。
定义:将一个类定义在另一个类的内部。内部的类称为内部类;
public class Outer{
class inner{
//省略
}
}
特点:
① 内部类可以很好的实现隐藏,可以使用protected,private修饰符;
② 内部类可以直接访问外部类的所有成员,包括私有成员;
③ 外部类不能直接访问内部类的成员,必须首先要建立内部类的对象才能访问;
④ 内部类可以解决一些问题,比如间接的去实现多继承。可以避免修改接口而实现同一个类中两种同名方法的调用;
成员内部类及应用
成员内部类特点:
① 成员内部类属于外部类的实例成员,成员内部类都可以有public,private,default,protected权限修饰符。在成员内部类中访问外部类的成员方法和属性,要使用“外部类名.this.成员方法”和“外部类名.this.成员属性”的形式;
② 创建成员内部类的实例使用“外部类名.内部类名.实例名=外部类实例名. new 内部类构造方法(参数)”的形式;
成员内部类有以下限制
① 成员内部类不能与外部类重名;
② 不能在成员内部类中定义static属性、方法和类(static,final形式的常量定义除外)。因为一个成员内部类实例必然与一个外部类实例关联,static成员完全可移到其外部类中去;
1 public class MemberInnerClass{
2 public static void main(String []args){
3 //创建外部类对象
4 Outer1 outer=new Outer1();
5 //创建内部类对象
6 Outer1.Inner1 inner=outer.new Inner1();
7 inner.innerShow();
8
9 System.out.println("--------------外部类访问内部类对象--------------");
10 outer.outerShow();
11 }
12 }
13
14 class Outer1{
15 private String name="张三";
16 private int num1=10;
17 public void outerShow(){
18 System.out.println(name);
19 System.out.println(num1);
20 //System.out.println(num2);//外部类不能直接访问内部类的成员
21
22 //外部类访问内部类对象
23 Inner1 inner =new Inner1();
24 inner.innerShow();
25 }
26
27 //当内部类改成私有时private,仅能在外部类中访问
28 public class Inner1{
29 private String name="李四";
30 private int num2=20;
31 private static final int num3=30;//静态常量在内部类中是可以使用的
32 //private static int num3=30;//在成员内部类中不能声明静态成员和静态方法
33 public void innerShow(){
34 System.out.println(name);
35 System.out.println(num2);
36
37 //成员内部类可以直接访问外部类的属性和方法,包括私有的
38 System.out.println("--------------");
39 //外部类访问内部类时注释outerShow(),避免死循环
40 //outerShow();
41
42 //打印外部类中成员属性
43 System.out.println("--------------打印外部类中成员属性--------------");
44 System.out.println(Outer1.this.name);
45 System.out.println(Outer1.this.num1);
46 }
47 }
48 }
用内部类间接实现多继承
1 public class MultiExtendsDemo{
2 public static void main(String []args){
3 C c=new C();
4 //间接实现多继承
5 c.showA();
6 c.showB();
7 }
8 }
9
10 class A{
11 public void showA(){
12 System.out.println("A");
13 }
14 }
15
16 class B{
17 public void showB(){
18 System.out.println("B");
19 }
20 }
21
22 class C{
23 private class A1 extends A{
24 public void showA(){
25 super.showA();
26 }
27 }
28
29 private class B1 extends B{
30 public void showB(){
31 super.showB();
32 }
33 }
34
35 public void showA(){
36 new A1().showA();
37 }
38
39 public void showB(){
40 new B1().showB();
41 }
42 }
父类中和接口中的方法名相同
为了不更改其方法且要实现这个2个方法
采用内部类的方式来实现
1 public class Demo2{
2 public static void main(String []args){
3 Son son=new Son();
4 son.show();
5 son.show2();
6 }
7 }
8
9 abstract class Parent{
10 public abstract void show();
11 }
12
13 interface IShow{
14 public abstract void show();
15 }
16
17 /*class Son extends Parent implements IShow{
18 public void show(){
19
20 }
21 public void show1(){
22
23 }
24 }*/
25
26 //因为父类中和接口中的方法名相同
27 //为了不更改其方法且要实现这个2个方法
28 //采用内部类的方式来实现
29 //但最好的方式还是改方法
30 class Son extends Parent{
31 public void show(){
32 System.out.println("抽象类中的show方法");
33 }
34
35 private class Inner2 implements IShow{
36 public void show(){
37 System.out.println("接口中的show方法");
38 }
39 }
40
41 public void show2(){
42 Inner2 inner=new Inner2();
43 inner.show();
44 }
45 }
静态内部类及其应用
静态内部类特点:
① 使用static修饰的成员内部类叫静态内部类;
② 静态内部类跟外部类没有任何关系,只是在生成类名和类定义时有影响。静态内部类可以看作是与外部类平级的类。使用方式与外部类平级的类完全相同;
③ 创建静态内部类的实例使用 外部类名.内部类名. 实例名=new 外部类名.内部类名(参数);
静态内部类有以下限制:
① 静态内部类的名字不能与外部相同;
② 静态内部类不能访问外部类的非静态的属性和方法,外部类不能访问内部类的非静态的属性和方法;
1 public class StaticInnerClass{
2 public static void main(String []args){
3 Outer2.Inner2 inner=new Outer2.Inner2();//构造一个静态内部类对象
4 inner.innerShow();
5
6 Outer2 outer=new Outer2();
7 outer.outerShow();
8 }
9 }
10
11 class Outer2{
12 private String name="张三";
13 private int num1=10;
14 private static int num3=100;
15 public void outerShow(){
16 System.out.println(name);
17 System.out.println(num1);
18
19 //System.out.println(Inner2.name);
20 Inner2 inner =new Inner2();
21 System.out.println(inner.name);//访问非静态
22
23 System.out.println(Inner2.num3);//访问静态
24 }
25
26 public static class Inner2{
27 private String name="李四";
28 private int num2=20;
29 private static final int num3=30;
30
31 public void innerShow(){
32 System.out.println(name);
33 System.out.println(num2);
34
35 //System.out.println(Outer2.this.name);//静态内部类不能访问外部类的非静态成员
36 System.out.println(Outer2.num3);
37 System.out.println(num2);
38 }
39 }
40 }
匿名内部类及应用
匿名内部类特点:
① 匿名内部类时没有名称的内部类,没办法引用它们。必须在创建时,作为new语句的一部分来声明并创建它们的实例;
② 匿名内部类必须继承一个类(抽象的,非抽象的都可以)或者实现一个接口。如果父类(或父接口)是抽象类,则匿名内部类必须实现其所有抽象方法;
③ 匿名内部类中可以定义代码块,用于实例的初始化,但是不能定义静态代码块;
匿名内部类的语法:new interface/superclass(){//类体}
这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口,并同时创建该匿名类的一个新实例;
不使用匿名内部类时
1 public class AnonymousInnerClass{
2 public static void main(String []args){
3 Person person=new Person();
4 Animal dog=new Dog();
5 person.feed(dog);
6 }
7 }
8
9 abstract class Animal{
10 public abstract void eat();
11 }
12
13 class Person{
14 public void feed(Animal animal){
15 animal.eat();
16 }
17 }
18
19 class Dog extends Animal{
20 public void eat(){
21 System.out.println("啃骨头");
22 }
23 }
使用匿名内部类
1 public class AnonymousInnerClass{
2 public static void main(String []args){
3 Person person=new Person();
4 //Animal dog=new Dog();
5 //person.feed(dog);
6
7 /*Animal dog=*/new IAnimal(){
8 private String name="aa";
9
10 //代码块
11 {
12 name="哈哈";
13 }
14
15 //不能使用静态代码块
16 //static{}
17 public void eat(){
18 System.out.println("啃骨头");
19 }
20 public void show(){
21 System.out.println(name);
22 }
23 }.show();//调用内部的show();
24
25 //person.feed(dog);
26 //dog.show();//这里不能调用定义的show();
27 //person.feed(dog);
28 person.feed(new IAnimal(){
29 public void eat(){
30 System.out.println("吃鱼");
31 }
32 });
33 }
34 }
35
36 //抽象类
37 //使用接口时先注释
38 //并修改Person类中的Animal为IAnimal
39 /*abstract class Animal{
40 public abstract void eat();
41 }*/
42
43 //接口
44 interface IAnimal{
45 public abstract void eat();
46 }
47
48 class Person{
49 public void feed(IAnimal animal){
50 animal.eat();
51 }
52 }
53
54 /*class Dog extends Animal{
55 public void eat(){
56 System.out.println("啃骨头");
57 }
58 }*/
局部内部类及应用
局部内部类的特点:
① 定义在代码块、方法体内的类叫局部内部类;
② 局部内部类访问外部类的属性和方法使用“外部类名.this.属性名”和“外部类名.this.方法名(参数)”的形式;
③ 对外部世界完全隐藏,只能在其作用域内生成对象;
局部内部类有以下限制:
① 局部内部类不能加访问修饰符,因为它们不能类成员;
② 成员内部类不能与外部类重名;
③ 局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰;
1 public class LocalInnerClass{
2 public static void main(String []args){
3 Outer3 outer=new Outer3();
4 outer.showOuter();
5 }
6 }
7
8 class Outer3{
9 private String name="张三";
10 private int num1=10;
11 private static int num2=20;
12 public void showOuter(){
13 /*final*/ int num4=50;//这里加不加final都可以被内部类访问?希望看到的且知道的帮我解答下
14 //局部内部类不能加访问修饰符
15 class Inner3{
16 private int num3=30;
17 private int num1=20;
18 public void showInner(){
19 System.out.println(num3);
20 System.out.println(num1);
21
22 System.out.println(Outer3.this.num1);
23 System.out.println(Outer3.num2);
24
25 System.out.println(num4);
26 }
27 }
28 Inner3 inner=new Inner3();
29 inner.showInner();
30 }
31 }
以上是关于Java学习(十六)成员内部类,静态内部类,匿名内部类,局部内部类的主要内容,如果未能解决你的问题,请参考以下文章
Java语言中四种内部类(成员内部类,局部内部类,静态内部类,匿名内部类)在实际使用中有啥好处?