• 成员内部类,静态内部类,匿名内部类,局部内部类


    定义:将一个类定义在另一个类的内部。内部的类称为内部类;

    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 }
    View Code

    用内部类间接实现多继承

     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 }
    View Code

    父类中和接口中的方法名相同

    为了不更改其方法且要实现这个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 }
    View Code

     

    静态内部类及其应用

    静态内部类特点

    ①   使用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 }
    View Code

     

    匿名内部类及应用

    匿名内部类特点

    ①   匿名内部类时没有名称的内部类,没办法引用它们。必须在创建时,作为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 }
    View Code

    使用匿名内部类

     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 }*/
    View Code

    局部内部类及应用

    局部内部类的特点

    ①   定义在代码块、方法体内的类叫局部内部类;

    ②   局部内部类访问外部类的属性和方法使用“外部类名.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 }
    View Code
  • 相关阅读:
    Spring.Net AOP的通知类型及通知链
    Spring.Net框架介绍及基本配置(学习笔记一)
    Spring.Net对方法的注入(学习笔记三)
    Spring通过容器获取配置对象及事件注入(学习笔记二)
    SqlServer2008 数据库同步的两种方式(Sql JOB)
    AOPUnity使用初探
    PIABPolicy Injection Application Block
    LINQ查询基础
    C#泛型基础
    [转载]CSS块级元素和行内元素
  • 原文地址:https://www.cnblogs.com/wzy330782/p/5303838.html
Copyright © 2020-2023  润新知