Maison > Java > javaDidacticiel > Partage d'exemples de code de classes internes Java

Partage d'exemples de code de classes internes Java

黄舟
Libérer: 2017-09-21 09:43:45
original
1520 Les gens l'ont consulté

Cet article présente principalement les informations pertinentes sur des exemples détaillés de classes internes Java. J'espère que grâce à cet article, tout le monde pourra comprendre et maîtriser l'utilisation des classes internes Java. Les amis dans le besoin pourront se référer à

Classes internes Java Explication détaillée des exemples

Vous pouvez mettre la définition d'une classe à l'intérieur de la définition d'une autre classe, qui est une classe interne.

Les classes internes sont une fonctionnalité très utile mais difficile à comprendre et à utiliser (je n'ai jamais utilisé de classes internes jusqu'à présent, et je ne connais que peu les classes internes).

Première rencontre

Les classes internes sont très faciles à comprendre de l'extérieur. Elles ne sont rien d'autre que définir une classe à l'intérieur d'une classe.


public class OuterClass {
  private String name ;
  private int age;

  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;
  }

  class InnerClass{
    public InnerClass(){
      name = "chenssy";
      age = 23;
    }
  }
}
Copier après la connexion
Ici InnerClass est la classe interne Pour les débutants, les classes internes ne sont pas beaucoup utilisées Moi, novice, je ne les ai jamais utilisées (ça semble être juste. Utilisé uniquement dans les événements d'inscription swing), mais à mesure que nos compétences en programmation s'améliorent, nous réaliserons son charme et il pourra être utilisé pour concevoir la structure de notre programme avec plus d'élégance. Avant d'utiliser des classes internes, nous devons comprendre pourquoi nous devrions utiliser des classes internes et quels avantages les classes internes peuvent nous apporter.

1. Pourquoi utiliser des classes internes ?

Pourquoi utiliser des classes internes ? Il y a cette phrase dans "Think in Java": La raison la plus intéressante pour utiliser des classes internes est que chaque classe interne peut hériter indépendamment d'une implémentation (d'interface), donc peu importe si la classe externe a hérité d'une implémentation (d'interface) ) n'a pas effet sur les classes internes.

Dans notre programmation, il y a parfois des problèmes difficiles à résoudre à l'aide d'interfaces. À l'heure actuelle, nous pouvons utiliser la capacité fournie par les classes internes d'hériter de plusieurs classes concrètes ou abstraites pour résoudre ces problèmes de conception. . On peut dire que les interfaces ne résolvent qu'une partie du problème et que les classes internes rendent la solution de l'héritage multiple plus complète.


public interface Father {

}

public interface Mother {

}

public class Son implements Father, Mother {

}

public class Daughter implements Father{

  class Mother_ implements Mother{

  }
}
Copier après la connexion
En fait, on ne voit vraiment pas les avantages d'utiliser des classes internes pour cet exemple, mais si Père et Mère ne sont pas des interfaces, mais des classes abstraites ou concret Et les cours ? Pour le moment, nous ne pouvons utiliser que des classes internes pour réaliser un héritage multiple.

En fait, le plus grand avantage de l'utilisation de classes internes est qu'elle peut très bien résoudre le problème de l'héritage multiple, mais si nous n'avons pas besoin de résoudre le problème de l'héritage multiple, alors nous pouvons naturellement utiliser un autre codage méthodes, mais utilisent des classes internes. Cela peut également nous apporter les fonctionnalités suivantes (extraites de "Think in java") :

1. Les classes internes peuvent utiliser plusieurs instances, chaque instance a ses propres informations d'état et est liée aux informations d'autres objets périphériques indépendants les uns des autres.

2. Dans une seule classe périphérique, plusieurs classes internes peuvent implémenter la même interface de différentes manières, ou hériter de la même classe.

3. L'heure à laquelle l'objet de classe interne est créé ne dépend pas de la création de l'objet de classe externe.

4. La classe interne n'a pas la relation déroutante "est-un", c'est une entité indépendante.

5. La classe interne offre une meilleure encapsulation À l'exception de la classe périphérique, les autres classes ne peuvent pas y accéder.


2. Notions de base des classes internes

Dans cette section, nous présentons principalement comment les classes internes utilisent les attributs et les méthodes des classes externes, et comment utiliser .this et .new.

Lorsque nous créons une classe interne, elle a une connexion invisible avec la classe externe. En s'appuyant sur cette connexion, elle peut avoir un accès illimité aux éléments de la classe externe.


public class OuterClass {
  private String name ;
  private int age;

  /**省略getter和setter方法**/

  public class InnerClass{
    public InnerClass(){
      name = "chenssy";
      age = 23;
    }

    public void display(){
      System.out.println("name:" + getName() +"  ;age:" + getAge());
    }
  }

  public static void main(String[] args) {
    OuterClass outerClass = new OuterClass();
    OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    innerClass.display();
  }
}
--------------
Output:
name:chenssy  ;age:23
Copier après la connexion
Dans cette application, nous pouvons voir que l'InnerClass interne peut accéder de manière transparente aux propriétés de la classe externe OuterClass, bien qu'elle soit privée modifiée . En effet, lorsque nous créons un objet de classe interne d'une classe externe, l'objet de classe interne capturera définitivement une référence à cet objet de classe externe. Tant que nous accéderons aux membres de la classe externe, nous utiliserons cette référence. la classe englobante.

En fait, dans cette application, nous avons également vu comment référencer des classes internes : Pour référencer des classes internes, nous devons spécifier le type de cet objet : OuterClasName.InnerClassName. En même temps, si nous devons créer un objet de classe interne, nous devons utiliser l'objet de classe externe pour créer la classe interne via .new : OuterClass.InnerClass innerClass = externalClass.new InnerClass();.

En même temps, si nous devons générer une référence à un objet de classe externe, nous pouvons utiliser OuterClassName.this, afin qu'une référence à la classe externe puisse être générée correctement. Bien entendu, cela est connu au moment de la compilation et il n’y a aucun coût d’exécution.


/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class OuterClass {
  public void display(){
    System.out.println("OuterClass...");
  }

  public class InnerClass{
    public OuterClass getOuterClass(){
      return OuterClass.this;
    }
  }

  public static void main(String[] args) {
    OuterClass outerClass = new OuterClass();
    OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    innerClass.getOuterClass().display();
  }
}
-------------
Output:
OuterClass...
Copier après la connexion
À ce stade, nous devons préciser que la classe interne est un concept au moment de la compilation, une fois compilée avec succès, elle et la classe externe appartiennent à deux. des catégories complètement différentes (il existe bien sûr encore des liens entre elles). Pour une classe périphérique nommée OuterClass et une classe interne nommée InnerClass, après une compilation réussie, deux fichiers de classe apparaîtront : OuterClass.class et OuterClass$InnerClass.class.

En Java, les classes internes sont principalement divisées en classes internes membres, classes internes locales, classes internes anonymes et classes internes statiques.

3. Classe interne des membres

成员内部类也是最普通的内部类,它是外围类的一个成员,所以他是可以无限制的访问外围类的所有 成员属性和方法,尽管是private的,但是外围类要访问内部类的成员属性和方法则需要通过内部类实例来访问。

在成员内部类中要注意两点,第一:成员内部类中不能存在任何static的变量和方法;第二:成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。


public class OuterClass {
  private String str;

  public void outerDisplay(){
    System.out.println("outerClass...");
  }

  public class InnerClass{
    public void innerDisplay(){
      //使用外围内的属性
      str = "chenssy...";
      System.out.println(str);
      //使用外围内的方法
      outerDisplay();
    }
  }

  /*推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 */
  public InnerClass getInnerClass(){
    return new InnerClass();
  }

  public static void main(String[] args) {
    OuterClass outer = new OuterClass();
    OuterClass.InnerClass inner = outer.getInnerClass();
    inner.innerDisplay();
  }
}
--------------------
chenssy...
outerClass...
Copier après la connexion

推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 。

四、局部内部类

有这样一种内部类,它是嵌套在方法和作用于内的,对于这个类的使用主要是应用与解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类,局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。

对于局部内部类实在是想不出什么好例子,所以就引用《Think in java》中的经典例子了。

定义在方法里:


/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class Parcel5 {
  public Destionation destionation(String str){
    class PDestionation implements Destionation{
      private String label;
      private PDestionation(String whereTo){
        label = whereTo;
      }
      public String readLabel(){
        return label;
      }
    }
    return new PDestionation(str);
  }

  public static void main(String[] args) {
    Parcel5 parcel5 = new Parcel5();
    Destionation d = parcel5.destionation("chenssy");
  }
}
Copier après la connexion

定义在作用域内:


public class Parcel6 {
  private void internalTracking(boolean b){
    if(b){
      class TrackingSlip{
        private String id;
        TrackingSlip(String s) {
          id = s;
        }
        String getSlip(){
          return id;
        }
      }
      TrackingSlip ts = new TrackingSlip("chenssy");
      String string = ts.getSlip();
    }
  }

  public void track(){
    internalTracking(true);
  }

  public static void main(String[] args) {
    Parcel6 parcel6 = new Parcel6();
    parcel6.track();
  }
}
Copier après la connexion

五、匿名内部类

在做Swing编程中,我们经常使用这种方式来绑定事件


button2.addActionListener( 
        new ActionListener(){ 
          public void actionPerformed(ActionEvent e) { 
            System.out.println("你按了按钮二"); 
          } 
        });
Copier après la connexion

我们咋一看可能觉得非常奇怪,因为这个内部类是没有名字的,在看如下这个例子:


/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class OuterClass {
  public InnerClass getInnerClass(final int num,String str2){
    return new InnerClass(){
      int number = num + 3;
      public int getNumber(){
        return number;
      }
    };    /* 注意:分号不能省 */
  }

  public static void main(String[] args) {
    OuterClass out = new OuterClass();
    InnerClass inner = out.getInnerClass(2, "chenssy");
    System.out.println(inner.getNumber());
  }
}

interface InnerClass {
  int getNumber();
}

----------------
Output:
Copier après la connexion

这里我们就需要看清几个地方

1、 匿名内部类是没有访问修饰符的。

2、 new 匿名内部类,这个类首先是要存在的。如果我们将那个InnerClass接口注释掉,就会出现编译出错。

3、 注意getInnerClass()方法的形参,第一个形参是用final修饰的,而第二个却没有。同时我们也发现第二个形参在匿名内部类中没有使用过,所以当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。

4、 匿名内部类是没有构造方法的。因为它连名字都没有何来构造方法。

六、静态内部类

在java提高篇——关键字static中提到Static可以修饰成员变量、方法、代码块,其他它还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类,不过我们更喜欢称之为嵌套内部类。静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着:

1、 它的创建是不需要依赖于外围类的。

2、 它不能使用任何外围类的非static成员变量和方法。


/**
 * Java学习交流QQ群:589809992 我们一起学Java!
 */
public class OuterClass {
  private String sex;
  public static String name = "chenssy";

  /**
   *静态内部类
   */
  static class InnerClass1{
    /* 在静态内部类中可以存在静态成员 */
    public static String _name1 = "chenssy_static";

    public void display(){
      /* 
       * 静态内部类只能访问外围类的静态成员变量和方法
       * 不能访问外围类的非静态成员变量和方法
       */
      System.out.println("OutClass name :" + name);
    }
  }

  /**
   * 非静态内部类
   */
  class InnerClass2{
    /* 非静态内部类中不能存在静态成员 */
    public String _name2 = "chenssy_inner";
    /* 非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的 */
    public void display(){
      System.out.println("OuterClass name:" + name);
    }
  }

  /**
   * @desc 外围类方法
   * @author chenssy
   * @data 2013-10-25
   * @return void
   */
  public void display(){
    /* 外围类访问静态内部类:内部类. */
    System.out.println(InnerClass1._name1);
    /* 静态内部类 可以直接创建实例不需要依赖于外围类 */
    new InnerClass1().display();

    /* 非静态内部的创建需要依赖于外围类 */
    OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
    /* 方位非静态内部类的成员需要使用非静态内部类的实例 */
    System.out.println(inner2._name2);
    inner2.display();
  }

  public static void main(String[] args) {
    OuterClass outer = new OuterClass();
    outer.display();
  }
}
----------------
Output:
chenssy_static
OutClass name :chenssy
chenssy_inner
OuterClass name:chenssy
Copier après la connexion

上面这个例子充分展现了静态内部类和非静态内部类的区别。

到这里内部类的介绍就基本结束了!对于内部类其实本人认识也只是皮毛,逼近菜鸟一枚,认知有限!我会利用这几天时间好好研究内部类!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal