30/09/2018, 20:09

Tại sao có thể gọi private method từ 1 object được khai báo từ, trong class trùng tên chứa private method đó?

Mình vô tình mò được đoạn code java sau và không hiểu sao nó lại chạy đc:

   public class test {
    private int a = 10;
    private void printA() {
        System.out.println(a);
    }

    public test(int a) {
        this.a = a;
    }
    
    public void callPrintA() {
        test bla = new test(1000);
        bla.printA();
    }
}

Tại sao object bla lại có thể gọi được method printA() trong khi nó là private? Và mình có đọc thì private chỉ cho phép trong nội bộ class hiện hành. Vậy khi new bla() thì nó ra 1 object mới nhưng sao vẫn có truyền truy cập printA() mọi người nhỉ? Trong khi nếu mình làm như code dưới thì sẽ báo lỗi đúng như tính chất của nó.

public class Blabla {
    public static void main(String[] args) throws IOException {
        test bla = new test(100);
        //bla.printA(); Netbean sẽ báo lỗi
        bla.callPrintA(); // in ra 1000
    }
}

Vậy không lẽ 2 object trên có bản chất khác nhau? @_@
Mình nghĩ là khác nhau :? Nhưng không rõ khác chỗ nào.
Mọi người giải thích giúp mình với. Ko rõ Kw nên chả biết GG như thế nào
Thanks nhiều

EDIT: Phát hiện ra là object như trên có thể truy cập đc mọi thứ chứ ko riêng gì private method. :c

Gió viết 22:16 ngày 30/09/2018

private là riêng của class chứ không phải của object. Chúng cùng class thì không có gì che dấu hết

*grab popcorn* viết 22:24 ngày 30/09/2018

Vậy tức là
bla.printA là gọi private method trong class, chứ không phải từ object ư?
Kiểu như printA(test) { print test.a }
Chứ không phải là printA(bla) {print bla.a} phải không gió???

Trong khi hàm main, thì nó mới đúng là
printA(bla) {print bla.a} :???

Gió viết 22:12 ngày 30/09/2018

Hiểu thế này nhé. Hàm printA thì private rồi. Nó không thể gọi ngoài class. Còn cái callprintA vì this là 1 ojebct của test nên có thể gọi hàm printA của bla

*grab popcorn* viết 22:20 ngày 30/09/2018

Cảm ơn gió.
Nhưng vẫn chưa thông đc gió ơi @_@
Kiểu như sao this gọi đc printA của bla ấy :?

Thành Phạm viết 22:09 ngày 30/09/2018

Đang định đi ngủ lại thấy topic hay [quote=“Gio, post:4, topic:23066”]
this
[/quote]

Em thấy ở đây có 2 object khác nhau mà, nếu this.printA() thì sẽ ra 100, OK, hợp lí, cơ mà bla.printA() thì có gì đó không ổn

Ví dụ:

Với code này:

class test {
    private int a = 10;
    private void printA() {
        System.out.println(a);
    }

    public test(int a) {
        this.a = a;
    }
    
    public void callPrintA() {
        test bla = new test(1000);
        bla.printA();
        this.printA();
        System.out.println("2: " + System.identityHashCode(bla));
        System.out.println("3: " + System.identityHashCode(this));
    }

}

public class BlaBla {
    public static void main(String[] args) {
        test bla = new test(100);
        System.out.println("1: " + System.identityHashCode(bla) );
        //bla.printA(); Netbean sẽ báo lỗi
        bla.callPrintA(); // in ra 1000
        
    }
}
sẽ được:
1: 366712642
1000
100
2: 1829164700
3: 366712642

Aha, Kiếm được mấy cái link

stackoverflow.com
softwarelover

Why can a "private" method be accessed from a different instance?

java, private
asked by softwarelover on 07:06AM - 20 Feb 14
stackoverflow.com
Ahmed Atteya

Why can I invoke a private method on an instance of the sub-class when it shouldn't be visible to the instance?

java, polymorphism, instance, private
asked by Ahmed Atteya on 09:16PM - 02 Nov 15

Yes, the main method belongs to class A, but it is not accessing the private method from inside the current object in the context of the “this” reference.

That doesn’t matter. That’s just not the model of accessibility that Java uses. What’s important is the class in which the code is written, not whether it’s accessing members in the same object.

Mai Anh Dũng viết 22:12 ngày 30/09/2018

Topic hay, cái này C++ cũng làm được. Miễn là vẫn còn nằm trong đoạn code định nghĩa class đó thì cái gì, thuộc về class đó, ta cũng gọi được.

Lúc trước có dùng mẹo này để code cái gì đấy mà không nhớ nên viết tạm cái ví dụ này trong C++.

#include <iostream>
using namespace std;
 
class daynhauhoc {
	private: void say_hello() { cout << "hello\n"; }
	public: void do_nothing() { 
		daynhauhoc dnh;
		dnh.say_hello();
	}
};
 
int main() {
	daynhauhoc ltd;
	ltd.do_nothing();
	return 0;
}
Ideone.com

Ideone.com

Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.

*grab popcorn* viết 22:25 ngày 30/09/2018

Cảm ơn mọi người :)) mông Não đã được thông rồi.

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

Và câu trên có vẻ như áp dụng cho inner class, outer class luôn.
Inner class có thể gọi được cả private member từ outer class và outer class có thể chơi được luôn với cả inner class member.

stackoverflow.com
user236215

In Java nested classes, can the enclosing class access private members of inner classes?

java, inner-classes
asked by user236215 on 12:47PM - 08 Feb 10

stackoverflow.com
mparaz

Why do inner classes make private methods accessible?

java, inner-classes
asked by mparaz on 05:01PM - 19 Mar 09

Thành Phạm viết 22:14 ngày 30/09/2018

Có phải là hàm equals hoặc compare không a

This is very useful, as otherwise (for example) it would be impossible to implement an equals method using private members of both classes.

Lúc đầu em cứ nghĩ private là chỉ truy cập bằng this, hóa ra private ý là chỉ truy cập được ở trong class (nằm trong phần code class đó)

Mai Anh Dũng viết 22:19 ngày 30/09/2018

Có phải là hàm equals hoặc compare không a

À đúng rồi, chính xác =)) lúc làm mấy cái Operators Overloading. Không có cái này thì làm sao mà lấy được mấy cái biến private

Code ví dụ
Ở đây feetinches là private, nhưng trong hàm void operator=(const Distance &D ) ta gọi thoải mái.

#include <iostream>
using namespace std;
 
class Distance
{
   private:
      int feet;             // 0 to infinite
      int inches;           // 0 to 12
   public:
      // required constructors
      Distance(){
         feet = 0;
         inches = 0;
      }
      Distance(int f, int i){
         feet = f;
         inches = i;
      }
      void operator=(const Distance &D )
      { 
         feet = D.feet;
         inches = D.inches;
      }
      // method to display distance
      void displayDistance()
      {
         cout << "F: " << feet <<  " I:" <<  inches << endl;
      }
      
};
int main()
{
   Distance D1(11, 10), D2(5, 11);

   cout << "First Distance : "; 
   D1.displayDistance();
   cout << "Second Distance :"; 
   D2.displayDistance();

   // use assignment operator
   D1 = D2;
   cout << "First Distance :"; 
   D1.displayDistance();

   return 0;
}

Nguồn: http://www.tutorialspoint.com/cplusplus/assignment_operators_overloading.htm

Đỗ Mạnh Hà viết 22:15 ngày 30/09/2018

Có thể bạn đã hiểu rồi nhưng mình sẽ giải thích cho bạn 1 cách đơn giản hơn như sau:

hàm private printA() nó được gọi bởi hàm anh em trong cùng 1 class là hàm public callPrintA() nên việc gọi hàm printA() là hoàn toàn có thể và đúng luật.

trong hàm main() bạn gọi tới hàm public callPrintA() -> hợp lệ. hàm callPrintA() gọi tới anh em của nó là hàm printA() -> hợp lệ (dù có là hàm private vì 2 hàm đó là anh em với nhau chứ không phải trong hàm main() gọi trực tiếp đến hàm private printA() thì mới là không hợp lệ).

Bài liên quan
0