web-dev-qa-db-ja.com

Java Encapsulation Concept not clear

これは基本的な質問ですが、それでもカプセル化の概念がわかりません。クラスのパブリックインスタンス値を設定しようとするたびに、そのクラスのオブジェクトを作成し、値を設定する必要があるため、クラスのプロパティを他のクラスから変更する方法を理解できませんでした。すべてのオブジェクトは異なるメモリを参照します.soインスタンス値を変更しても、他のオブジェクトには影響しません。

静的パブリックインスタンス値を使用して変更しようとしても、クラスプロパティ値を変更することもできません。

例を以下に示します

// Employee class
public class Employee {
    public static int empid;
    public static String empname;

    public static void main(String[] args) {
        System.out.println("print employe details:"+empid+" "+empname);
    }

    // EmployeeTest  class
    public class EmployeeTest {

        public static void main(String[] args) {
            Employee e = new Employee();
            e.empid=20;
            e.empname="jerry";
            Employee.empid=10;
            Employee.empname="tom";
        }

    }
}

Employeeクラスを実行するたびに同じ値が得られます

print employe details:0 null

カプセル化の概念に従っていませんが、従業員クラスのパブリックインスタンス値を変更することはできませんが、間違っている概念を理解するのを手伝ってください。

24
user2693404

ええ、これは少し混乱することがあります。ステップバイステップで行きましょう:最初に、理解する必要があります

  • カプセル化とは何ですか、なぜ使用されるのですか?

カプセル化は、4つの基本的なOOP概念)の1つです。カプセル化は、クラスのフィールドをプライベートにするテクニックですフィールドがプライベートとして宣言されている場合、クラス外の誰もアクセスできないため、クラス内のフィールドが非表示になります。このため、カプセル化は「カプセル化」とも呼ばれます。データ隠蔽。

カプセル化は、クラス外で定義された他のコードによってランダムにアクセスされるコードとデータを防止する保護バリアとして説明できます。データとコードへのアクセスは、インターフェイスによって厳密に制御されます。

カプセル化の主な利点は、コードを使用する他の人のコードを壊すことなく実装されたコードを変更できることです。この機能によりカプセル化により、コードに保守性、柔軟性、および拡張性が与えられます

小さな例を挙げます。

public class EncapTest{

   private String name;
   private String idNum;
   private int age;

   public int getAge(){
      return age;
   }

   public String getName(){
      return name;
   }

   public String getIdNum(){
      return idNum;
   }

   public void setAge( int newAge){
      age = newAge;
   }

   public void setName(String newName){
      name = newName;
   }

   public void setIdNum( String newId){
      idNum = newId;
   }
}

上記のメソッドは、アクセサ(別名ゲッターおよびセッター)と呼ばれます。今、あなたは尋ねるかもしれません、

  • アクセサを使用する理由..?実際には、クラスのフィールドを直接公開するのではなく、アクセサの使用を検討するのに多くの理由があります。

たとえば、他のクラスによってアクセスされるクラスのパブリックフィールドを考えてみてください。後で、変数の取得と設定中に追加のロジックを追加する必要があります。これは、APIを使用する既存のクライアントに影響します。そのため、このパブリックフィールドを変更するには、それを参照する各クラスを変更する必要があります。それどころか、アクセサメソッドを使用すると、データをキャッシュするなどのロジックを簡単に追加し、後で遅延初期化できます。さらに、新しい値が前の値と異なる場合、プロパティ変更イベントを起動できます。これはすべて、アクセサメソッドを使用して値を取得するクラスに対してシームレスです。

それらがどのように、そして何であるかについて、非常に多くのチュートリアルと説明があります。それらをグーグル。

あなたの現在の問題に関して:

  1. 2つの異なるクラスがあり、それぞれにメインがあります。それは間違いです。それらには異なるプロパティがあります。
  2. @Subhrajyoti Majumderによって提案されたコード変更は正しいものです。問題を解決するための答えを確認してください。

それまでの間、

概念をよりよく理解するため。それが役に立てば幸い。 :)

39
user2339071

2つの異なるクラスを別々に実行しており、EmployeeTestを実行するときに属性に加えられた変更がEmployee runに反映されると仮定しています。変更は同じJREインスタンスに反映されることに注意してください。あなたの問題を誤解してしまった場合は、すみません。

編集:ユーザー入力に従って。静的メンバー値にアクセスして更新する方法を以下に示します。

class Employee {
    public static int empid;
    public static String empname;

    public static void main(String[] args) {
        System.out.println("print employe details:" + empid + " " + empname);
    }
}

// EmployeeTest class
public class EmployeeTest {

    public static void main(String[] args) {
        Employee e = new Employee();
        e.empid = 20;
        e.empname = "jerry";
        Employee.empid = 10;
        Employee.empname = "tom";
        Employee.main(null);
    }

}
6
Juned Ahsan

public staticフィールドはオブジェクトではなくクラスに関連付けられ、オブジェクトのカプセル化規則に違反します。

カプセル化された2つのフィールドを持つEmployeeクラスempid & empname

public class Employee {
    private int empid;
    private String empname;

    public int getEmpid(){
        return this.empid;
    } 
    public void setEmpid(int empid){
        this.empid = empid;
    }
    ...
}

public class EmployeeTest {
      public static void main(String[] args) {
            Employee e = new Employee();
            e.setempId(1);
            Employee e1 = new Employee();
            e1.setempId(2);
      }
}

カプセル化の理解を深めるためのドキュメント

カプセル化は、コードとデータがクラス外で定義された他のコードによってランダムにアクセスされるのを防ぐ保護バリアですデータとコードへのアクセスは、インターフェイスによって厳密に制御されます

Javaでのカプセル化は、クラス内のフィールドをプライベートにし、パブリックメソッドを介してフィールドへのアクセスを提供する技術です。

フィールドがプライベートとして宣言されている場合、クラス外の誰もアクセスできないため、クラス内のフィールドは非表示になります。このため、カプセル化はdata hidingとも呼ばれます。

リアルタイムの例:車と所有者車のすべての機能は所有者でカプセル化されています。したがって、他の誰もアクセスできません。

以下は、この例のコードです。

public class Main {

  public static void main(String[] args) {
    Owner o1=new Car("SONY","Google Maps");
    o1.activate_Sunroof();
    o1.getNavigationSystem();
    o1.getRadioSytem();
 }
}  
//Interface designed for exposing car functionalities that an owner can use.
public interface Owner {
     void getNavigationSystem();
     void getRadioSytem();
     void activate_Sunroof();
}
/*
Car class protects the code and data access from outside world access by implementing Owner interface(i.e, exposing Cars functionalities) and restricting data access via private access modifier.
*/
public class Car implements Owner {
                private String radioSystem;
                private String gps;

                public Car(String radioSystem, String gps) {
                    super();
                    this.radioSystem = radioSystem;
                    this.gps = gps;
                }

                public String getRadioSystem() {
                    return radioSystem;
                }

                public void setRadioSystem(String radioSystem) {
                    this.radioSystem = radioSystem;
                }

                public String getGps() {
                    return gps;
                }

                public void setGps(String gps) {
                    this.gps = gps;
                }

                @Override
                public void getNavigationSystem() {
                    System.out.println("GPS system " + getGps() + " is in use...");
                }

                @Override
                public void getRadioSytem() {
                    System.out.println("Radio system " + getRadioSystem() + " activated");
                }

                @Override
                public void activate_Sunroof() {
                    System.out.println("Sunroof activated");
                }
}
2
Rohit Gaikwad

encapsulation = VARIABLES(let a a、b、c)+ METHODS(setA&getA、setB&getB ....)private修飾子を使用してカプセル化できます。あなたのクラスで作成された1つのパブリック変数と1つのプライベート変数を考えてみましょう...あなたがそれらの変数を読み取り専用のために別のクラスに与える必要がある場合(彼らは見ることができ、変更することはできません)パブリック変数またはメソッド。ただし、getメソッドを提供することにより、プライベートで実行できます。そのため、クラスのプライベート変数またはメソッドは管理下にあります。しかし、公の場ではチャンスはありません....私はあなたが理解できると思います。

1
n ramesh
Encapsulation means combining data and code together(class). The main purpose of encapsulation is you would have full control on data by using the code.

class Encap{

private int amount;

public void setAmount(int amount)
{
this.amount = amount;
}

Here, you can set the amount using the setAmount method, but value should be more than 100. So, i have the control on it.

public void setAmount(int amount)
{
if(amount>100)
this.amount = amount;
}
1
Satheesh Guduri

カプセル化の概念は、情報隠蔽に関連するdesignテクニックです。基本的な原則は、適切に設計されたインターフェイスを介して、クラス属性への保護されたアクセスを提供することです。カプセル化の目的は、クラスの不変条件を強制することです。

あなたの例をフォローするには、このクラスのインターフェースを考えてください:

class Employee

  private final String firstName;
  private final String lastName;    

  public Employee(final firstName, final lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public String getName() {
    return firstName + " " + lastName;
  }
}

属性をプライベートとして宣言することにより、このクラスはクライアントが従業員オブジェクトインスタンスの状態に直接アクセスすることを制限することに注意してください。クライアントがクライアントにアクセスする唯一の方法は、getName()メソッドを使用することです。つまり、これらの属性はクラスによってカプセル化されます。また、属性をfinalとして宣言し、コンストラクターで初期化することにより、効果的に不変のクラス、つまり、構築後に状態を変更できないクラスを作成することに注意してください。

代替の実装は次のとおりです。

class Employee

  private String firstName;
  private String lastName;    

  public Employee(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public String getName() {
    return firstName + " " + lastName;
  }

  public String setName(String firstName, String lastName) {

    if (firstName == null) {
      throw new IllegalArgumentException("First name cannot be null");
    }

    if (lastName == null) {
      throw new IllegalArgumentException("Last name cannot be null");
    }

    this.firstName = firstName;
    this.lastName = lastName;
  }
}

この例では、オブジェクトは不変ではありませんが、オブジェクトへのアクセスはアクセサーと修飾子を介してのみ行われるため、オブジェクトの状態はカプセル化されます。ここで、カプセル化がオブジェクト状態の不変式の保護にどのように役立つかに注意してください。メソッドを介して変更を制約することにより、オブジェクトの状態の変更方法をより適切に制御し、検証を追加して、変更がクラスの仕様と一致することを確認します。

1

もちろん、あるオブジェクトを変更しても、別のオブジェクトには影響しません。クラス学生があり、学校のすべての子供がオブジェクトであるとします。学校を辞めたとしても、これは他のすべての学生(学生クラスのオブジェクト)も学校を辞めるべきだという意味ではありません。

カプセル化とは、クラス変数をprivateにする概念であり、だから誰も外の世界のデータメンバーと直接遊ぶことはできません。しかし、あなたはpublicメソッドを提供し、外の世界があなたの望むようにあなたのデータメンバーと遊ぶようにします。カプセル化のニースコーディング例は、上記のSubhrajyoti Majumderによって提供されています。

(静的メンバーは、クラスのすべてのオブジェクトで同じです。例:学生クラスオブジェクトの数をカウントするための静的カウント変数(学校の生徒数))。

次のように編集します:

例:

public class student{
    public String name;
    public student() {}
 }

そしてあなたのメイン関数では、外界はあなたのクラス属性で次のように遊ぶことができます

student s = new student();
s.name = "xyz";

外側の世界でオブジェクトのname属性を変更させたくないとしましょう。次に、名前を「name」としてプライベートにし、名前を表示するだけのpublicメソッドを提供する必要があります(get)。

例:

public class student{
    private String name;
    public student() {}
    public String getName(){
      return this.name;
      }
 }

そして今、あなたのメインメソッドでは、名前オブジェクトのみを取得でき、最初の例のように新しい値に設定することはできません。

student s = new student();
String sname = s.getName();

そしてあなたが試してみると:

s.name = "newname";

コンパイラはそれを許可しません。プライベートメンバーにアクセスする権限がないためです。

1
Zeeshan

Empidの値は、0とnullではなく10とempname tomである必要があると言うつもりですか?

1)変数へのメモリは実行時に割り当てられ、プログラムの終了後にも割り当て解除されます。

2)したがって、empidに10を与えると、常に10になるはずだと思う場合、そうではありません。empidは単に「10」を格納しているメモリへの参照であるためです。

3)したがって、割り当て解除によって、プログラムが終了した後、empidが10を格納しているメモリ領域を指していなくなったことを意味します

4)新しいプログラムを実行するたびに、empidは現在他のメモリ領域を指しており、そのメモリには、静的変数の場合、それぞれのデータ型に従ってデフォルト値が割り当てられます。したがって、常に0およびnullです。

0
Purvi Modi

ENCAPSULATIONは、メソッドと変数を1つのユニットとしてラップするメカニズムです。例えば、カプセル、すなわちいくつかの薬の混合。

クラスの変数はプライベートとして宣言されるため、他のクラスから隠され、現在のクラスのメソッドを介してのみアクセスできます

Javaでカプセル化を実現するには-*クラスの変数をプライベートとして宣言します。 *変数の値を変更および表示するためのpublic setterおよびgetterメソッドを提供します。 * Java Beanクラスは、完全にカプセル化されたクラスの例です。

0
smriti

Employeeクラスの実行時に出力「print employeese details:0 null」を取得する理由は、これらの変数が初期化されていないためです。つまり、Employeeクラス内では値を割り当てません。

EmployeeTestクラス内で何をしても、次に実行されるときにEmployeeの変数の値には影響しません。 Javaプログラムを「きれいなスレート」にプログラムするたびに考えてください。

カプセル化の点では、staticキーワードを実際に使用しないでください。カプセル化を行う場合は、この質問に対する他の回答を確認してください。使用できる素敵なコードサンプルがあります。

0
William Gaul

カプセル化はOOPの概念です。クラスはデータ+動作を含むカプセルのように考えられます。データはプライベートであり、ゲッターおよびセッターと呼ばれるパブリックメソッドを使用してのみアクセスする必要があります。 this encapsulation この概念の詳細についてはチュートリアル。

0
Abderrahmen