ホームページ  >  記事  >  Java  >  JavaSE オブジェクト指向クラス、継承、ポリモーフィズム

JavaSE オブジェクト指向クラス、継承、ポリモーフィズム

PHPz
PHPzオリジナル
2017-04-04 11:10:571368ブラウズ

授業は理解していますか?

  • 1 Java では、クラス ファイルは接尾辞 .java が付いたコード ファイルです。各クラス ファイルに含めることができるパブリック クラスは 1 つだけです。パブリック クラスがある場合、クラス ファイルの名前は次のようにする必要があります。 public クラスと同じです。 public クラスが存在しない場合、クラス ファイルの名前は任意の名前になります。

  • 2 クラス内で、メンバー変数について、定義時に明示的な代入の初期化がない場合、Java はクラスの各メンバー変数が適切に初期化されていることを確認します
    1) char、short、byte、基本データの変数の場合int、long、float、double などの型はデフォルトで 0 に初期化されます (ブール変数はデフォルトで false に初期化されます)。
    2) 参照型変数の場合、デフォルトで null に初期化されます。

  • 3 コンストラクターが明示的に定義されていない場合、コンパイラーはパラメーターなしのコンストラクターを自動的に作成します。コンストラクターが明示的に定義されている場合、コンパイラーはコンストラクターを自動的に追加しません。デフォルトではすべてのコンストラクターが静的であることに注意してください。

  • 4 クラスがオブジェクトをインスタンス化する順序
    1) プログラムが実行されると、Java 実行エンジンはまず、クラスがロードされているかどうかを確認します。オブジェクトが最初にロードされるので、オブジェクトを再度生成します。ロードされている場合は、オブジェクトを直接生成します。
    2) クラスのロード処理中に、クラスの静的メンバー変数が初期化されます。また、クラス内に静的ステートメント ブロックがある場合は、静的ステートメント ブロックが実行されます。静的メンバー変数と静的ステートメント ブロックの実行順序は、コード内の順序と一致します。
    3) Java では、クラスはオンデマンドでロードされます。このクラスは必要なときに 1 回だけロードされます。
    次の例を見て理解してください:

    public class Bread {
      static {
          System.out.println("Bread is loaded");
      }
      public Bread() {
          System.out.println("bread");
      }
      public static void main(String[] args) throws ClassNotFoundException {
          Bread bread1 = new Bread();
          Bread bread2 = new Bread();
      }
    }

    このコードを実行すると、「Bread isloaded」が 1 回だけ出力されることがわかります。
    4) オブジェクトを生成するプロセスでは、最初にオブジェクトのメンバー変数が初期化され、その後コンストラクターが実行されます。これは、変数がメソッド定義の間に散在している場合でも、クラス内の変数はメソッド (コンストラクターを含む) が呼び出される前に初期化されることを意味します。

    public class Test {
      public static void main(String[] args)  {
          new Meal();
      }
    } 
    class Meal {     
      public Meal() {
          System.out.println("meal");
      }
      Bread bread = new Bread();
    }
    class Bread {     
      public Bread() {
          System.out.println("bread");
      }
    }

    出力結果は次のようになります:

    bread
    meal

継承について理解していますか?

  • 1 継承
    1) 継承はすべての OOP 言語に不可欠な部分であり、Java では継承関係を示すために extends キーワードが使用されます。クラスを作成すると、継承するクラスが明示的に指定されていない場合は、常にルート クラスの Object から暗黙的に継承されます。たとえば、次のコード:

    class Person {
      public Person() {
    
      }
    }
    class Man extends Person {
      public Man() {
    
      }
    }

    2) Man が person クラスから継承するクラス。この場合、person クラスは親クラス (基本クラス) と呼ばれ、Man クラスはサブクラス (派生クラス) と呼ばれます。 。 2 つのクラス間に継承関係がある場合、サブクラスは親クラスのメソッドと変数を自動的に継承し、親クラスのメソッドと変数をサブクラスで呼び出すことができます。
    3) Java では、単一継承のみが許可されます。つまり、クラスは最大でも 1 つの親クラスからのみ明示的に継承できます。ただし、クラスは複数のクラスに継承できます。つまり、クラスは複数のサブクラスを持つことができます。

  • 2 サブクラスは親クラスの属性を継承します
    サブクラスは、あるクラスを継承する際、親クラスのメンバ変数を利用することができますが、親クラスのメンバ変数をすべて完全に継承するわけではありません。具体的な原則は次のとおりです:
    1) 親クラスの public および protected メンバー変数は継承できますが、親クラスの private メンバー変数は継承できません。
    2) 親クラスのパッケージ アクセス許可メンバー変数の場合。 、サブクラスと親クラスが同じパッケージ内にある場合、サブクラスは継承できます。それ以外の場合、サブクラスは継承できません。
    3) サブクラスが継承できる親クラスのメンバー変数の場合、サブクラスに同じ名前が出現すると、 隠れ 現象が発生します。つまり、サブクラスのメンバー変数が、同じ名前の親クラスのメンバー変数をブロックします。親クラスの同名のメンバ変数にサブクラスでアクセスしたい場合は、super キーワードを使用して参照する必要があります。

  • 3 サブクラスは親クラスのメソッドを継承します
    同様に、サブクラスは親クラスのメソッドをすべて完全に継承するわけではありません。
    1) 親クラスのパブリックおよび保護されたメンバー メソッドを継承できますが、親クラスのプライベート メンバー メソッドは継承できません。
    2) サブクラスと親クラスが存在する場合、親クラスのパッケージ アクセス メンバー メソッドの場合。同じパッケージの場合、サブクラスは継承できます。それ以外の場合、サブクラスは継承できません。
    3) サブクラスが継承できる親クラスのメンバー メソッドの場合、同じ名前のメンバー メソッドがサブクラスに存在する場合、それは オーバーライド と呼ばれます。つまり、サブクラスのメンバー メソッドは、同じ名前の親クラスのメンバー メソッドをオーバーライドします。親クラスの同名のメンバメソッドにサブクラスでアクセスしたい場合は、superキーワードを使用して参照する必要があります。

  • 4 注意
    非表示とカバーは異なります。
    非表示はメンバー変数と静的メソッド用であり、
    オーバーライドは通常のメソッド用です。

  • 5 构造器
    1)子类是不能够继承父类的构造器,但是要注意的是,如果父类的构造器都是带有参数的,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。
    2)如果父类有无参构造器,则在子类的构造器中用super关键字调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。

  • 6 super主要有两种用法
    1)super.成员变量/super.成员方法;
    2)super(parameter1,parameter2....)
    第一种用法主要用来在子类中调用父类的同名成员变量或者方法;
    第二种主要用在子类的构造器中显示地调用父类的构造器
    要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。

你了解多态吗?

  • 1 子类必是父类,所以父类型的引用可以指向子类型的对象。

  • 2 动态绑定方法的多种不同版本(即非编译时绑定,而是晚绑定或者动态绑定)

    Parent p = new Child(); 
    p.eat();

    此时Parent和Child中必须都有eat()方法;
    即多态进行动态绑定的前提条件是继承,子类必须继承父类的方法,才能使用父类的引用进行方法调用。

  • 3 父类引用能向下转换成子类引用的前提是父类引用指向子类的对象。

  • 4 向下转换后的引用,就可以调用子类特有的方法了。

  • 5 多态的好处,定义方法时,出入参可以申明为父类的类型,传参时,可以传递子类的对象。这样在方法不改变的前提下,就可以扩展子类的种类,添加新的逻辑。

  • 6 覆盖方法才会进行动态绑定,而隐藏是不会发生动态绑定的。
    1)举例如下

    public class Test {
      public static void main(String[] args)  {
          Shape shape = new Circle();
          System.out.println(shape.name); // 成员变量(隐藏)
          shape.printName(); // 静态方法(隐藏)
          shape.printType(); // 非静态方法(覆盖)
      }
    }
    class Shape {
      public String name = "shape";
    
      public Shape(){
          System.out.println("shape constructor");
      }
    
      public void printType() {
          System.out.println("this is shape");
      }
    
      public static void printName() {
          System.out.println("shape");
      }
    }
    class Circle extends Shape {
      public String name = "circle";
    
      public Circle() {
          System.out.println("circle constructor");
      }
    
      public void printType() {
          System.out.println("this is circle");
      }
    
      public static void printName() {
          System.out.println("circle");
      }
    }

    2)输出结果:

    shape constructor
    circle constructor
    shape
    shape
    this is circle

    3)原因分析
    覆盖受RTTI(Runtime type  identification)约束的,而隐藏却不受该约束。也就是说只有覆盖方法才会进行动态绑定,而隐藏是不会发生动态绑定的。在Java中,除了static方法和final方法,其他所有的方法都是动态绑定。因此,就会出现上面的输出结果。

以上がJavaSE オブジェクト指向クラス、継承、ポリモーフィズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。