Các lớp con có kế thừa các trường riêng không?


245

Đây là một câu hỏi phỏng vấn.

Liệu các lớp con kế thừa các lĩnh vực tư nhân?

Tôi đã trả lời "Không", vì chúng tôi không thể truy cập chúng bằng "cách OOP thông thường". Nhưng người phỏng vấn nghĩ rằng họ được thừa kế, bởi vì chúng ta có thể truy cập các lĩnh vực đó một cách gián tiếp hoặc sử dụng sự phản chiếu và chúng vẫn tồn tại trong đối tượng.

Sau khi tôi trở lại, tôi đã tìm thấy trích dẫn sau trong javadoc :

Thành viên tư nhân trong một siêu lớp

Một lớp con không kế thừa các thành viên riêng của lớp cha của nó.

Bạn có biết bất kỳ lý lẽ cho ý kiến ​​của người phỏng vấn?


33
Tôi đã ở trong một tình huống tương tự một lần và tôi nhận ra tôi thậm chí không muốn làm việc cho một công ty nơi người phỏng vấn biết ít về Java hơn tôi. :)
biziclop

48
Một người phỏng vấn đôi khi sẽ không đồng ý với bạn ngay cả khi anh ta biết bạn đúng. Một người phỏng vấn giỏi sẽ cố gắng tìm hiểu về bạn nhiều hơn là kiến ​​thức kỹ thuật của bạn.
Andy Thomas

4
@DigitalRoss Đặc tả ngôn ngữ Java cũng được viết xấu? Xem câu trả lời RD01: stackoverflow.com/questions/4716040/
Kẻ

9
@Andy Thomas-Cramer Tôi sẽ không muốn làm việc với những người cố tình nói dối để kiểm tra phản ứng của tôi.
biziclop

4
Chà, tôi nghĩ trước tiên chúng ta nên tìm hiểu ý nghĩa của "sự kế thừa" trong Java. Lớp con không có trường riêng và lớp con có trường riêng nhưng không thể truy cập vào nó là khác nhau, lớp nào đề cập đến ý nghĩa chính xác của thừa kế trong Java?
MạnhT

Câu trả lời:


238

Hầu hết sự nhầm lẫn trong câu hỏi / câu trả lời ở đây bao quanh định nghĩa về Kế thừa.

Rõ ràng, như @DigitalRoss giải thích ĐỐI TƯỢNG của một lớp con phải chứa các trường riêng của lớp cha của nó. Như ông nói, không có quyền truy cập vào một thành viên tư nhân không có nghĩa là nó không có ở đó.

Tuy nhiên. Điều này khác với khái niệm thừa kế cho một lớp. Như trường hợp trong thế giới java, nơi có một câu hỏi về ngữ nghĩa, trọng tài là Đặc tả ngôn ngữ Java (hiện đang là phiên bản thứ 3).

Như các trạng thái JLS ( https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 ):

Các thành viên của một lớp được khai báo là riêng tư không được kế thừa bởi các lớp con của lớp đó. Chỉ các thành viên của một lớp được khai báo được bảo vệ hoặc công khai được kế thừa bởi các lớp con được khai báo trong một gói khác với lớp được khai báo.

Địa chỉ này câu hỏi chính xác gây ra bởi người phỏng vấn: "làm sub LỚP kế thừa lĩnh vực tư nhân". (nhấn mạnh thêm bởi tôi)

Câu trả lời là Không. Họ không. ĐỐI TƯỢNG của các lớp con chứa các trường riêng của siêu lớp của chúng. Bản thân lớp con KHÔNG CÓ THÔNG BÁO về các trường riêng của siêu lớp của nó.

Đó có phải là ngữ nghĩa của một bản chất nhi đồng? Đúng. Nó có phải là một câu hỏi phỏng vấn hữu ích? Chắc là không. Nhưng JLS thiết lập định nghĩa cho thế giới Java và nó làm như vậy (trong trường hợp này) một cách rõ ràng.

EDITED (đã xóa một trích dẫn song song từ Bjarne Stroustrup, do sự khác biệt giữa java và c ++ có lẽ chỉ làm tăng thêm sự nhầm lẫn. Tôi sẽ để câu trả lời của mình nghỉ ngơi trên JLS :)


3
@digital tại sao lại thở dài. Tôi hiểu bạn tin rằng bạn đúng. Tôi không đồng ý với bạn rằng kế thừa đối tượng là điều mà hầu hết các lập trình viên được dạy / nghĩ về. Nhưng định nghĩa JLS áp dụng trực tiếp cho câu hỏi ban đầu. Đó là ngữ nghĩa có, nhưng JLS xác định định nghĩa, không phải bạn hay tôi
robert_x44

4
Một cách để điều hòa tất cả những điều này là chỉ cần nhận ra rằng từ "kế thừa" được sử dụng theo hai cách rất khác nhau để mô tả mối quan hệ của các lớp dẫn xuất và lớp cha, ít nhất là trong thế giới Java. Vâng, JSL là có thẩm quyền. Vâng, điều đó có nghĩa là bạn có thể sử dụng "kế thừa" theo cách không may đó. Nhưng rõ ràng vẫn đúng là các lớp con ếch (vì bây giờ chúng ta không có từ nào) các trường riêng của lớp cha của chúng.
DigitalRoss

1
@digital Họ nằm trong đối tượng của lớp. không phải lớp học Simula gọi chúng là những đồ vật nối liền nhau. Khi một đối tượng của một lớp con được tạo ra, nó được tạo thành từ các 'đối tượng tiền tố' được nối. Đối tượng siêu lớp là một đối tượng tiền tố có thể chứa các đối tượng tiền tố khác. Tôi nghĩ thật kiêu ngạo khi nói rằng JLS có "từ ngữ rõ ràng xấu". Đối với những gì chúng ta sử dụng từ, thừa kế tất nhiên. Không có gì sai khi sử dụng thuật ngữ hơi mơ hồ. Lúc nào chả vậy. Nhưng điều đó không có nghĩa là không có một định nghĩa chính xác.
robert_x44

1
@digital Chúng tôi chắc chắn có thể đồng ý rằng từ này được sử dụng theo những cách khác nhau. :) Chúng tôi cũng có thể đồng ý rằng một câu hỏi phỏng vấn phụ thuộc vào một thuật ngữ mơ hồ có lẽ không phải là một câu hỏi hay.
robert_x44

2
Bất cứ ai cũng có một tài liệu tham khảo từ Java / Oracle cho "Các đối tượng của lớp con chứa các trường riêng của siêu lớp của chúng"? Tôi đồng ý với điều này, nhưng không thể tìm thấy bất kỳ tài liệu chính thức nào nói rằng.
MạnhT

78

Đúng

Điều quan trọng là nhận ra rằng trong khi có rất hai lớp, chỉ có một đối tượng.

Vì vậy, vâng, tất nhiên nó được thừa hưởng các lĩnh vực tư nhân. Chúng, có lẽ, rất cần thiết cho chức năng đối tượng thích hợp và trong khi một đối tượng của lớp cha không phải là đối tượng của lớp dẫn xuất, thì một thể hiện của lớp dẫn xuất chủ yếu là một thể hiện của lớp cha. Nó không thể là tốt mà không có tất cả các lĩnh vực.

Không, bạn không thể truy cập trực tiếp vào chúng. Vâng, họ được thừa kế. Họ phải như vậy.

Đó là một câu hỏi hay!


Cập nhật:

Ơ, "Không"

Chà, tôi đoán tất cả chúng ta đã học được điều gì đó. Vì JLS có nguồn gốc từ "không được thừa kế" chính xác, nên trả lời "không" là chính xác . Vì lớp con không thể truy cập hoặc sửa đổi các trường riêng tư, nên nói cách khác, chúng không được kế thừa. Nhưng có thực sự chỉ một đối tượng, nó thực sự có chứa các lĩnh vực tư nhân, và vì vậy nếu ai đó JLS và từ ngữ hướng dẫn một cách sai lầm, nó sẽ là khá khó khăn để hiểu được OOP, các đối tượng Java, và những gì đang thực sự xảy ra.

Cập nhật để cập nhật:

Cuộc tranh cãi ở đây liên quan đến một sự mơ hồ cơ bản: chính xác những gì đang được thảo luận? Các đối tượng? Hay chúng ta đang nói theo một nghĩa nào đó về chính lớp học? Rất nhiều vĩ độ được phép khi mô tả lớp đối lập với đối tượng. Vì vậy, lớp con không kế thừa các trường riêng, nhưng một đối tượng là một thể hiện của lớp con chắc chắn có chứa các trường riêng.


2
@ Ma99uS. Tất nhiên chúng được tái sử dụng. Đó là toàn bộ điểm thừa kế. Không có chúng, kiểu dẫn xuất sẽ không và không thể là một thể hiện của kiểu cha. OOP sẽ là vô nghĩa. Các loại đa hình sẽ ngừng hoạt động . Hiểu rằng chỉ có một đối tượng và bạn là một thể hiện của kiểu cha là rất quan trọng để hiểu OOP. Bạn phải vượt qua vấn đề này để hiểu nó.
DigitalRoss

2
Không chắc chắn ví dụ của cha là rất tốt bởi vì một trường có thể được kế thừa trong khi lớp cha vẫn còn sống và cũng có trường đó. Nếu thừa kế hoạt động theo cách đó tôi có thể thừa kế tiền của cha tôi khi ông còn sống và ông cũng có thể giữ tiền như vậy. Mỗi đứa con tôi đều có tiền và tiền của tôi.
Peter Lawrey

2
@Peter Lawrey không tranh cãi hay bất cứ điều gì, nhưng đây là những gì tôi nghĩ. Cha mẹ có một car, anh ta giữ nó trong privatetủ khóa mà đứa trẻ không phải là chìa khóa. Bạn thực sự thừa hưởng carnhưng nó vô dụng với bạn. Vì vậy, thực tế, bạn không được hưởng lợi từ thừa kế.
Nishant

1
@DigitalRoss. Tôi nhận được quan điểm của bạn. Mhh, chúng ta có thể nói giá trị là có vì định nghĩa cha mẹ không được kế thừa cũng được tải. :) Tôi nghĩ rằng đặc tả JVM sẽ có câu trả lời chính xác cho "KHÔNG CÓ CÔNG VIỆC" mà chúng tôi đang tìm kiếm. java.sun.com/docs/books/jvms
OscarRyz

5
-1, Đặc tả ngôn ngữ Java nói rõ rằng chúng không được kế thừa. Không có ifs, không buts. Họ chỉ đơn giản là không. Bất kỳ định nghĩa khác về thừa kế đều sai trong ngữ cảnh của Java.
biziclop

21

Không. Các lĩnh vực tư nhân không được kế thừa ... và đó là lý do tại sao Protected được phát minh. Đó là do thiết kế. Tôi đoán điều này biện minh cho sự tồn tại của sửa đổi được bảo vệ.


Bây giờ đến với bối cảnh. Ý bạn là gì khi được kế thừa - nếu nó có trong đối tượng được tạo từ lớp dẫn xuất? Vâng, đúng vậy.

Nếu bạn có nghĩa là nó có thể hữu ích cho lớp dẫn xuất. Ồ không.

Bây giờ, khi bạn đến với lập trình chức năng , trường riêng của siêu lớp không được kế thừa theo cách có ý nghĩa cho lớp con . Đối với lớp con, một trường riêng của siêu lớp cũng giống như trường riêng của bất kỳ lớp nào khác.

Về mặt chức năng, nó không được kế thừa. Nhưng lý tưởng , nó là.


OK, chỉ cần nhìn vào hướng dẫn Java, họ trích dẫn điều này:

Thành viên tư nhân trong một siêu lớp

Một lớp con không kế thừa các thành viên riêng của lớp cha của nó. Tuy nhiên, nếu siêu lớp có các phương thức công khai hoặc được bảo vệ để truy cập các trường riêng của nó, chúng cũng có thể được sử dụng bởi lớp con.

tham khảo: http://doad.oracle.com/javase/tutorial/java/IandI/subclasses.html

Tôi đồng ý, rằng lĩnh vực là ở đó. Nhưng, lớp con không nhận được bất kỳ đặc quyền nào trên trường riêng đó. Đối với một lớp con, trường riêng giống như bất kỳ trường riêng nào của bất kỳ lớp nào khác.

Tôi tin rằng đó hoàn toàn là vấn đề quan điểm. Bạn có thể nhào nặn tranh luận ở hai bên. Tốt hơn hết là nên biện minh cho cả hai cách.

 


2
Điều này LAF không đúng. Bạn không thể truy cập chúng, đó là chính xác. Nhưng họ phải được thừa kế như tôi đã giải thích.
DigitalRoss

1
câu trả lời tuyệt vời !!! +1 cho I believe it's purely matter of point-of-view.justified the existence of protected modifier.
Ravi

14

Nó phụ thuộc vào định nghĩa của bạn về "kế thừa". Lớp con vẫn có các trường trong bộ nhớ? Chắc chắn rồi. Nó có thể truy cập chúng trực tiếp? Không. Đó chỉ là sự tinh tế của định nghĩa; vấn đề là phải hiểu những gì đang thực sự xảy ra.


Chính xác. Nhưng tôi nghĩ trong câu hỏi cơ bản như vậy nên có câu trả lời chung)
Stan Kurilin

Tôi nghĩ đó là định nghĩa của Java về thừa kế.
OscarRyz

Hoặc nếu không, nó phụ thuộc vào định nghĩa của bạn về "lĩnh vực". Để xác định trường số nguyên "foo" là thuê một kho lưu trữ có kích thước nguyên và đặt dấu "foo" trên đó. Nếu trường được khai báo là riêng tư, lớp dẫn xuất kế thừa một khóa lưu trữ có kích thước nguyên không được gắn nhãn. Việc lớp dẫn xuất có kế thừa "trường" hay không phụ thuộc vào việc một người gọi khóa lưu trữ không được gắn nhãn đó là "trường".
supercat

10

Tôi sẽ chứng minh khái niệm với mã. Các lớp con THỰC SỰ kế thừa các biến riêng của siêu lớp. Vấn đề duy nhất là chúng không thể truy cập được vào các đối tượng con trừ khi bạn cung cấp các biểu đồ và setters công khai cho các biến riêng tư trong siêu lớp.

Xem xét hai lớp trong gói Dump. Con mở rộng Cha mẹ.

Nếu tôi nhớ chính xác, một đối tượng con trong bộ nhớ bao gồm hai vùng. Một phần chỉ là phần cha mẹ và phần còn lại chỉ là phần con. Một đứa trẻ có thể truy cập vào phần riêng tư trong mã của cha mẹ chỉ thông qua một phương thức công khai trong cha mẹ.

Nghĩ theo cách này. Cha Boltok của Borat có một két chứa 100.000 đô la. Anh ấy không muốn chia sẻ biến "riêng tư" của mình an toàn. Vì vậy, anh ta không cung cấp chìa khóa cho sự an toàn. Borat thừa hưởng sự an toàn. Nhưng, nó có ích gì nếu anh ta thậm chí không thể mở nó? Giá như bố anh đã cung cấp chìa khóa.

Cha mẹ -

package Dump;

public class Parent {

    private String reallyHidden;
    private String notReallyHidden;

    public String getNotReallyHidden() {
        return notReallyHidden;
    }

    public void setNotReallyHidden(String notReallyHidden) {
        this.notReallyHidden = notReallyHidden;
    }

}//Parent

Đứa trẻ -

package Dump;

public class Child extends Parent {

    private String childOnly;

    public String getChildOnly() {
        return childOnly;
    }

    public void setChildOnly(String childOnly) {
        this.childOnly = childOnly;
    }

    public static void main(String [] args){

        System.out.println("Testing...");
        Child c1 = new Child();
        c1.setChildOnly("childOnly");
        c1.setNotReallyHidden("notReallyHidden");

        //Attempting to access parent's reallyHidden
            c1.reallyHidden;//Does not even compile

    }//main

}//Child

10

Không. Họ không thừa kế nó.

Thực tế một số lớp khác có thể sử dụng nó một cách gián tiếp không nói gì về thừa kế, nhưng về đóng gói.

Ví dụ:

class Some { 
   private int count; 
   public void increment() { 
      count++;
   }
   public String toString() { 
       return Integer.toString( count );
   }
}

class UseIt { 
    void useIt() { 
        Some s = new Some();
        s.increment();
        s.increment();
        s.increment();
        int v = Integer.parseInt( s.toString() );
        // hey, can you say you inherit it?
     }
}

Bạn cũng có thể nhận được giá trị countbên trong UseItthông qua sự phản chiếu. Nó không có nghĩa là, bạn thừa hưởng nó.

CẬP NHẬT

Mặc dù giá trị là ở đó, nó không được kế thừa bởi lớp con.

Ví dụ, một lớp con được định nghĩa là:

class SomeOther extends Some { 
    private int count = 1000;
    @Override
    public void increment() { 
        super.increment();
        count *= 10000;
    }
}

class UseIt { 
    public static void main( String ... args ) { 
        s = new SomeOther();
        s.increment();
        s.increment();
        s.increment();
        v = Integer.parseInt( s.toString() );
        // what is the value of v?           
     }
}

Đây chính xác là tình huống tương tự như ví dụ đầu tiên. Thuộc tính countbị ẩn và không được kế thừa bởi lớp con. Tuy nhiên, như DigitalRoss chỉ ra, giá trị là có, nhưng không có nghĩa là thừa kế.

Đặt nó theo cách này. Nếu cha bạn giàu có và cho bạn thẻ tín dụng, bạn vẫn có thể mua đồ bằng tiền của mình, nhưng không có nghĩa là bạn đã thừa hưởng tất cả số tiền đó, phải không?

Cập nhật khác

Mặc dù vậy, nó rất thú vị để biết tại sao thuộc tính lại ở đó.

Tôi thực sự không có thuật ngữ chính xác để mô tả nó, nhưng đó là JVM và cách thức hoạt động của nó cũng tải định nghĩa cha mẹ "không được kế thừa".

Chúng tôi thực sự có thể thay đổi cha mẹ và lớp con vẫn sẽ hoạt động.

Ví dụ :

//A.java
class A {
   private int i;
   public String toString() { return ""+ i; }
}
// B.java
class B extends A {}
// Main.java
class Main {
   public static void main( String [] args ) {
      System.out.println( new B().toString() );
    }
}
// Compile all the files
javac A.java B.java Main.java
// Run Main
java Main
// Outout is 0 as expected as B is using the A 'toString' definition
0

// Change A.java
class A {
   public String toString() {
      return "Nothing here";
   }
}
// Recompile ONLY A.java
javac A.java
java Main
// B wasn't modified and yet it shows a different behaviour, this is not due to 
// inheritance but the way Java loads the class
Output: Nothing here

Tôi đoán thuật ngữ chính xác có thể được tìm thấy ở đây: Đặc tả máy ảo JavaTM


:) Lần sau bạn có thể mất cơ hội để giải thích phỏng vấn của bạn, nơi là anh / cô ấy sai, và điều này có thể cung cấp cho bạn thêm điểm;) Rõ ràng, bạn nên làm điều này một cách chính xác ngoại giao.
OscarRyz

1
Chúng phải được kế thừa cho các loại đa hình để có bất kỳ ý nghĩa nào cả. Xem giải thích của tôi. Đúng là bạn không thể nghịch ngợm với họ, nhưng họ ở đó. Họ phải như vậy.
DigitalRoss

Không có từ khóa kế thừa (mở rộng / thực hiện) trong mã của bạn để đó không phải là một ví dụ kế thừa.
fmucar

1
Uhh, nếu họ ở đó, làm thế nào họ đến đó? Bởi vì lớp con định nghĩa chúng? Không. Bởi vì họ, uhh, hmm, err, được thừa hưởng ?
DigitalRoss

1
Điểm tuyệt vời trên encapsulationvs inherit, tôi đoán câu trả lời này xứng đáng được bình chọn nhiều hơn.
Eric Wang

6

Vâng, câu trả lời của tôi cho câu hỏi của người phỏng vấn là - Các thành viên tư nhân không được kế thừa trong các lớp con nhưng họ chỉ có thể truy cập vào đối tượng của lớp con hoặc lớp con thông qua các phương thức getter hoặc setter công khai hoặc bất kỳ phương thức thích hợp nào của lớp gốc. Cách làm thông thường là giữ kín các thành viên và truy cập chúng bằng các phương thức getter và setter công khai. Vì vậy, điểm nào trong việc chỉ kế thừa các phương thức getter và setter khi thành viên riêng mà chúng xử lý không có sẵn cho đối tượng? Ở đây 'kế thừa' đơn giản có nghĩa là nó có sẵn trực tiếp trong lớp con để chơi xung quanh bởi các phương thức mới được giới thiệu trong lớp con.

Lưu tệp dưới đây dưới dạng ParentClass.java và tự mình thử ->

public class ParentClass {
  private int x;

  public int getX() {
    return x;
  }

  public void setX(int x) {
    this.x = x;
  }
}

class SubClass extends ParentClass {
  private int y;

  public int getY() {
    return y;
  }

  public void setY(int y) {
    this.y = y;
  }

  public void setXofParent(int x) {
    setX(x); 
  }
}

class Main {
  public static void main(String[] args) {
    SubClass s = new SubClass();
    s.setX(10);
    s.setY(12);
    System.out.println("X is :"+s.getX());
    System.out.println("Y is :"+s.getY());
    s.setXofParent(13);
    System.out.println("Now X is :"+s.getX());
  }
}

Output:
X is :10
Y is :12
Now X is :13

Nếu chúng tôi cố gắng sử dụng biến riêng x của ParentClass trong phương thức của SubClass thì nó không thể truy cập trực tiếp cho bất kỳ sửa đổi nào (có nghĩa là không được kế thừa). Nhưng x có thể được sửa đổi trong SubClass thông qua phương thức setX () của lớp gốc như được thực hiện trong phương thức setXofParent () HOẶC nó có thể được sửa đổi bằng cách sử dụng đối tượng ChildClass bằng phương thức setX () hoặc phương thức setXofParent () mà cuối cùng gọi setX (). Vì vậy, ở đây setX () và getX () là loại cổng cho thành viên riêng x của ParentClass.

Một ví dụ đơn giản khác là siêu lớp Clock có giờ và phút là thành viên riêng và các phương thức getter và setter thích hợp là công khai. Sau đó, DigitalClock là một lớp con của Đồng hồ. Ở đây nếu đối tượng của DigitalClock không chứa thành viên giờ và phút thì mọi thứ sẽ bị rối tung.


2
Theo tài liệu của Oracle - Một lớp con không kế thừa các thành viên riêng của lớp cha của nó. Tuy nhiên, nếu siêu lớp có các phương thức công khai hoặc được bảo vệ để truy cập các trường riêng của nó, chúng cũng có thể được sử dụng bởi lớp con.
dganesh2002

4

Ok, đây là một vấn đề rất thú vị mà tôi đã nghiên cứu rất nhiều và đi đến kết luận rằng các thành viên riêng của siêu lớp thực sự có sẵn (nhưng không thể truy cập được) trong các đối tượng của lớp con. Để chứng minh điều này, đây là một mã mẫu với lớp cha và lớp con và tôi đang viết đối tượng lớp con vào tệp txt và đọc một thành viên riêng có tên 'bhavesh' trong tệp, do đó chứng minh rằng nó thực sự có sẵn ở trẻ lớp nhưng không thể truy cập do sửa đổi truy cập.

import java.io.Serializable;
public class ParentClass implements Serializable {
public ParentClass() {

}

public int a=32131,b,c;

private int bhavesh=5555,rr,weq,refw;
}

import java.io.*;
import java.io.Serializable;
public class ChildClass extends ParentClass{
public ChildClass() {
super();
}

public static void main(String[] args) {
ChildClass childObj = new ChildClass();
ObjectOutputStream oos;
try {
        oos = new ObjectOutputStream(new FileOutputStream("C:\\MyData1.txt"));
        oos.writeObject(childObj); //Writing child class object and not parent class object
        System.out.println("Writing complete !");
    } catch (IOException e) {
    }


}
}

Mở MyData1.txt và tìm kiếm thành viên riêng có tên 'bhavesh'. Xin hãy cho tôi biết các cậu đang nghĩ gì.


3

Dường như một lớp con kế thừa các trường riêng trong đó các trường này được sử dụng trong các hoạt động bên trong của lớp con (nói theo triết học). Một lớp con, trong hàm tạo của nó, gọi hàm tạo của lớp bậc trên. Các trường riêng của siêu lớp rõ ràng được kế thừa bởi lớp con gọi hàm tạo của lớp bậc trên nếu hàm tạo của lớp bậc trên đã khởi tạo các trường này trong hàm tạo của nó. Đó chỉ là một ví dụ. Nhưng tất nhiên, không có phương thức truy cập, lớp con không thể truy cập vào các trường riêng của siêu lớp (giống như không thể bật bảng mặt sau của iPhone để lấy pin ra để đặt lại điện thoại ... nhưng pin vẫn ở đó).

PS Một trong nhiều định nghĩa về thừa kế mà tôi đã bắt gặp: "Kế thừa - một kỹ thuật lập trình cho phép một lớp dẫn xuất mở rộng chức năng của lớp cơ sở, kế thừa tất cả STATE (nhấn mạnh là của tôi) và hành vi."

Các trường riêng, ngay cả khi lớp con không thể truy cập được, là trạng thái được kế thừa của lớp cha.


1

Tôi sẽ phải trả lời rằng các trường riêng trong Java được kế thừa. Cho phép tôi chứng minh:

public class Foo {

    private int x; // This is the private field.

    public Foo() {
        x = 0; // Sets int x to 0.
    }

    //The following methods are declared "final" so that they can't be overridden.
    public final void update() { x++; } // Increments x by 1.
    public final int getX() { return x; } // Returns the x value.

}


public class Bar extends Foo {

    public Bar() {

        super(); // Because this extends a class with a constructor, it is required to run before anything else.

        update(); //Runs the inherited update() method twice
        update();
        System.out.println(getX()); // Prints the inherited "x" int.

    }

}

Nếu bạn chạy trong một chương trình Bar bar = new Bar();, thì bạn sẽ luôn thấy số "2" trong hộp đầu ra. Bởi vì số nguyên "x" được gói gọn với các phương thức update()getX()sau đó có thể chứng minh rằng số nguyên được kế thừa.

Điều khó hiểu là bởi vì bạn không thể truy cập trực tiếp vào số nguyên "x", nên mọi người cho rằng nó không được kế thừa. Tuy nhiên, mọi thứ không tĩnh trong một lớp, có thể là trường hoặc phương thức, được kế thừa.


3
"Chứa" không có nghĩa là "thừa kế";)
Stan Kurilin

1

Bố cục bộ nhớ trong kế thừa Java vis-a-vis

nhập mô tả hình ảnh ở đây

Các bit đệm / Sắp xếp và bao gồm Lớp đối tượng trong VTABLE không được xem xét. Vì vậy, đối tượng của lớp con có một vị trí cho các thành viên riêng của lớp Siêu. Tuy nhiên, nó không thể được truy cập từ các đối tượng của lớp con ...


1

Không , các lĩnh vực tư nhân không được kế thừa. Lý do duy nhất là lớp con không thể truy cập chúng trực tiếp .


0

Tôi tin rằng, câu trả lời hoàn toàn phụ thuộc vào câu hỏi, đã được hỏi. Ý tôi là, nếu câu hỏi là

Chúng ta có thể truy cập trực tiếp vào trường riêng của siêu hạng từ lớp phụ của họ không?

Sau đó, câu trả lời là Không , nếu chúng ta đi qua các chi tiết của trình xác định truy cập , nó được đề cập, các thành viên riêng chỉ có thể truy cập trong chính lớp đó.

Nhưng, nếu câu hỏi là

Chúng ta có thể truy cập vào trường riêng của siêu hạng từ lớp phụ của họ không?

Điều đó có nghĩa là, nó không quan trọng, bạn sẽ làm gì để truy cập vào thành viên tư nhân. Trong trường hợp đó, chúng tôi có thể tạo phương thức công khai trong siêu hạng và bạn có thể truy cập thành viên riêng. Vì vậy, trong trường hợp này, bạn đang tạo một giao diện / cầu nối để truy cập thành viên riêng.

Ngôn ngữ OOP khác như C ++, có friend functionkhái niệm, qua đó chúng ta có thể truy cập thành viên riêng của lớp khác.


0

Chúng ta có thể chỉ đơn giản nói rằng khi một siêu lớp được kế thừa, thì các thành viên riêng của siêu lớp thực sự trở thành các thành viên riêng của lớp con và không thể được thừa kế thêm hoặc không thể truy cập được vào các đối tượng của lớp con.



-1

Một lớp con không kế thừa các thành viên riêng của lớp cha của nó. Tuy nhiên, nếu siêu lớp có các phương thức công khai hoặc được bảo vệ để truy cập các trường riêng của nó, chúng cũng có thể được sử dụng bởi lớp con.


-2

Thành viên tư nhân (nhà nước và hành vi) được thừa kế. Chúng (có thể) ảnh hưởng đến hành vi và kích thước của đối tượng được lớp khởi tạo. Không phải đề cập đến việc chúng có thể nhìn thấy rất rõ đối với các lớp con thông qua tất cả các cơ chế phá vỡ bao vây có sẵn hoặc có thể được giả định bởi những người thực hiện chúng.

Mặc dù thừa kế có định nghĩa "defacto", nhưng nó chắc chắn không có liên kết đến các khía cạnh "khả năng hiển thị", được giả định bởi các câu trả lời "không".

Vì vậy, không cần phải ngoại giao. JLS chỉ sai ở điểm này.

Bất kỳ giả định rằng chúng không được "thừa kế" là không an toàn và nguy hiểm.

Vì vậy, trong số hai định nghĩa mâu thuẫn defacto (một phần) (mà tôi sẽ không lặp lại), định nghĩa duy nhất nên tuân theo là định nghĩa an toàn hơn (hoặc an toàn).


1
-1. JLS định nghĩa ngôn ngữ, JLS không thể "sai". Ngoài ra, nếu có các cơ chế phá vỡ đóng gói, điều đó không có nghĩa là trường được kế thừa; chỉ đơn thuần là có những cơ chế lật đổ sự đóng gói.
SL Barth - Phục hồi Monica

Một định nghĩa có thể tự nó sai theo nhiều cách. Thảo luận thêm về điều này không phải là ý định của tôi. Đối số ở đây không phải là về các cơ chế phá vỡ đóng gói (thần hoặc xấu như chúng có thể) mà trên thực tế trường / phương thức ở đó, ảnh hưởng đến hành vi và trạng thái của lớp con của bạn. Vì vậy, nó là "di truyền". Người ta có thể sử dụng một mảng byte riêng 100kb trong một lớp và chỉ cần giả sử rằng hậu duệ (jumbo) của mình không kế thừa nó. Đừng bỏ lỡ quan điểm và đánh giá đây là một thực tiễn tốt hay xấu (cường điệu giúp đưa ra quan điểm): đó là một hành động hợp pháp, có thể thấy trước. Thành viên tư nhân được "thừa kế".
gkakas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.