powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Убейте
25 сообщений из 55, страница 1 из 3
Убейте
    #34082096
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хоть убейте, но обьясните плиз, что здесь неправильно
Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
	 protected   void  v(){}
}	

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 package  package2;
 public   class  Class2  extends  package1.Class1 {
	 public   void  v(){}
	
	 public   static   void  main(String[] args){
		package1.Class1 c =  new  Class2();
		c.v(); 	//Class2.java:8: 
			//v() has protected access in package1.Class1
	
		Class2 c =  new  Class2();
		c.v(); 	//OK
	}
}	
...
Рейтинг: 0 / 0
Убейте
    #34082113
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.math.rsu.ru/mexmat/pmp/student/book/Chapter06.html
Итак вы только что получили представление о наследовании и теперь пришло время раскрыть смысл ключевого слова protected. В идеальном мире, private объекты всегда являются действительно private, но в реальных проектах, где вы пытаетесь во многих местах скрыть от внешнего мира нечто, Вам часто нужна возможность получить к нему доступ из классов наследников. Ключевое слово protected поэтому не такая уж и ненужная назойливость или догма. Оно объявляет "Этот объект частный (private), если к нему пытается подобраться пользователь, но он доступен для всех остальных находящихся в том же самом пакете(package)".

Читайте основы.
...
Рейтинг: 0 / 0
Убейте
    #34082126
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я предполагал, что в обоих случаях c.v() - это вызов переписанного public метода package2.Class2.v()???
...
Рейтинг: 0 / 0
Убейте
    #34082221
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У классиков (The Java Language Specification, Third Edition) нашел такое:

6.6.7 Example: protected Fields, Methods, and Constructors
Consider this example, where the points package declares:package points;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 public   class  Point {
         protected   int  x, y;
         void  warp(threePoint.Point3d a) {
                 if  (a.z >  0 )         // compile-time error: cannot access a.z
                        a.delta( this );
        }
}
and the threePoint package declares:package threePoint;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
 import  points.Point;
 public   class  Point3d  extends  Point {
         protected   int  z;
         public   void  delta(Point p) {
                p.x +=  this .x;          // compile-time error: cannot access p.x
                p.y +=  this .y;          // compile-time error: cannot access p.y

        }
         public   void  delta3d(Point3d q) {
                q.x +=  this .x;
                q.y +=  this .y;
                q.z +=  this .z;
        }
}
which defines a class Point3d. A compile-time error occurs in the method delta here: it cannot access the protected members x and y of its parameter p, because while Point3d (the class in which the references to fields x and y occur) is a subclass of Point (the class in which x and y are declared), it is not involved in the implementation of a Point (the type of the parameter p). The method delta3d can access the protected members of its parameter q, because the class Point3d is a subclass of Point and is involved in the implementation of a Point3d.

Но это же не мой случай???
...
Рейтинг: 0 / 0
Убейте
    #34082265
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ноль2
Но это же не мой случай???
Почему же не ваш?
...
Рейтинг: 0 / 0
Убейте
    #34082404
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Объект класса 2 объявляется как объект класса 1. Их этого следует, что через эту ссылку (ее тип класс 1) доступны поля и методы, а так же область их доступности, только те, которые относятся к классу1 (к родительскому).
Меня лично заинтересовало другое - получается, что в этом самом объекте существет один и тот же метод, который в разных случаях имеет разную степень доступа к нему.
...
Рейтинг: 0 / 0
Убейте
    #34082419
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наверно потому, что
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
 package  package2;

 import  java.lang.reflect.*;

 public   class  Class2  extends  package1.Class1 {
     public   void  v() {
    }

     public   static   void  main(String[] args) {
        package1.Class1 c =  new  Class2();
         for  (Method m : c.getClass().getMethods()) {
            System.out.println(m.toString());
        }
/*
        c.v(); 	                 //Class2.java:8: 
                                           //v() has protected access in package1.Class1
        Class2 c = new Class2();
        c.v(); 	                 //OK
*/
    }
}
сообщает о своих методах:

public void package2.Class2.v()
public static void package2.Class2.main(java.lang.String[])

public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public java.lang.String java.lang.Object.toString()

и не слова о public void package1.Class1.v(),
то есть c.v() может быть только вызовом public void package2.Class2.v()???
...
Рейтинг: 0 / 0
Убейте
    #34082498
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я до сих пор думал, что если имеет место overriding, то какой будет вызван метод определяется не типом package1.Class1 переменной с, а классом обьекта package2.Class2, на который она, переменная с, указывает???
...
Рейтинг: 0 / 0
Убейте
    #34082590
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
АСУ ТПшникОбъект класса 2 объявляется как объект класса 1. Их этого следует, что через эту ссылку (ее тип класс 1) доступны поля и методы, а так же область их доступности, только те, которые относятся к классу1 (к родительскому).
Меня лично заинтересовало другое - получается, что в этом самом объекте существет один и тот же метод, который в разных случаях имеет разную степень доступа к нему.

Это не верно для overriding методов!!!???
...
Рейтинг: 0 / 0
Убейте
    #34082615
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Protected
Следующим спецификатором уровня доступа является спецификатор "защищенный" -- protected, который разрешает обращаться к членам класса самому классу, его суб-класссам (с упомянутыми ранее ограничениями), а также всем классам в той же самой библиотеке. Уровень доступа protected используют в случаях, если к члену класса нужно разрешить доступ из его суб-классов, но не из самостоятельных не связанных с ним классов. Защищенные члены (protected members) подобны семейным секретам -- вы не думаете, что об этом знает вся семья и даже некоторые ближайшие друзья, но вы не хотите, чтобы об этом знал кто-либо со стороны.
Для объявления защищенного члена служит ключевое слово protected. Сначала давайте посмотрим, как спецификатор protected влияет на доступ для классов в той же самой библиотеке. Рассмотрим следующую версию класса Alpha, которая теперь объявлена внутри библиотеки с именем Greek и которая имеет одну защищенную переменную и один защищенный метод:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 package  Greek;

 class  Alpha {
  protected   int  iamprotected;
  protected   void  protectedMethod() {
 System.out.println("protectedMethod");
 }
}
Теперь предположим, что класс Gamma уже был объявлен как член библиотеки Greek (и не является суб-классом класса Alpha). Класс Gamma может легально обращаться к переменной iamprotected объекта Alpha и может вполне легально вызывать его метод protectedMethod:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 package  Greek;

 class  Gamma {
  void  accessMethod() {
 Alpha a =  new  Alpha();
 a.iamprotected =  10 ; // legal
 a.protectedMethod(); // legal
 }
}
Это достаточно очевидно. Теперь давайте посмотрим, как спецификатор protected влияет на доступ для суб-классов класса Alpha.
Давайте введем новый класс Delta, который получен из класса Alpha, но прописан в другой библиотеке -- Latin. Класс Delta может обращаться к iamprotected и к protectedMethod, но только для объектов типа Delta или их суб-классов. Класс Delta не может обращаться к iamprotected или protectedMethod для объектов типа Alpha. accessMethod в следующем примере пытается обратиться к к переменной iamprotected, являющейся member variable для объекта типа Alpha, что недопустимо, и к объекту типа Delta, что разрешено. Аналогично, accessMethod вытается вызвать метод protectedMethod объекта Alpha, что также недопустимо:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 import  Greek.*;

 package  Latin;

 class  Delta  extends  Alpha {
  void  accessMethod(Alpha a, Delta d) {
 a.iamprotected =  10 ; // illegal
 d.iamprotected =  10 ; // legal
 a.protectedMethod(); // illegal
 d.protectedMethod(); // legal
 }
}
Если класс является суб-классом и находится в той же самой библиотеке, что и класс с защищенными членами, то класс имеет доступ к защищенным членам.

From tutorial http://www.javable.com
...
Рейтинг: 0 / 0
Убейте
    #34082620
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Последняя фраза ключевая.
...
Рейтинг: 0 / 0
Убейте
    #34082759
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так все просто. На момент компиляции же не известно, какой тип объекта хранится в ссылочной переменной
Код: plaintext
1.
package1.Class1 c;
Поэтому и не дается возможность вызова protected методов.
...
Рейтинг: 0 / 0
Убейте
    #34082804
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Последняя фраза ключевая для понимания особенности, которая присуща потомку класса (а именно: он хоть и потомок, но доступ получить к протектед только если в том же пакете находится).
А тут акцент немного на другое - является ли в приведенном примере запись v как метода с другим уровнем доступа overriding и более того, если класс потомок имеет переопределенный метод, то если объект этого класса объявить как объект родительского типа, то в вызове (Родительский класс) Объект.метод () будет использовано содержимое метода исходного или переопределнного. Что впрочем легко проверить, работы много, надо будет сделать тест.
Хотя делов то...

Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
	 public   void  v(){System.out.println ("Вызван метод родителя");}
}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
package package2;
public class Class2 extends package1.Class1 {
	public void v (){System.out.println ("Вызван метод потомка");}
	
	public static void main(String[] args){
		package1.Class1 c = new Class2();
		c.v(); 	
                          Class2 c2 = new Class2();
		c2.v(); 	//OK
	}
}
хм... самое прикольно в том что результат - вызыван класс потомка в обоих случаях... что то недопонимаю, ведь тогда даже пи overridinge остается активным вариант реализации метода как указано в потомке...
...
Рейтинг: 0 / 0
Убейте
    #34082818
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторto Leonidov
эээ не совсем понял.
...
Рейтинг: 0 / 0
Убейте
    #34082825
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeonidvНу так все просто. На момент компиляции же не известно, какой тип объекта хранится в ссылочной переменной
Код: plaintext
1.
package1.Class1 c;
Поэтому и не дается возможность вызова protected методов.
Да все там известно. Если Packege1.v1() сделать public все будет работать.
...
Рейтинг: 0 / 0
Убейте
    #34082852
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 package  ru.spb.leonidv.learn.pack1;

 public   class  Parent {
	 protected   void  proc() {
		System.out.println("parent");
	};
}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 package  ru.spb.leonidv.learn.pack2;

 import  ru.spb.leonidv.learn.pack1.Parent;

 public   class  Child  extends  Parent {

	@Override
	 public   void  proc() {
		System.out.println("Child");
	}
	
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 public   class  PrivateProtectedInheritance {

	/**
	 * @param args
	 */
	 public   static   void  main(String[] args) {
		Parent p =  new  Parent();
		Parent cp =  new  Child();
		Child c =  new  Child();
		//p.proc();		
		///cp.proc();
		c.proc();
	}

}
Закоменнтированные строчки не работают, по указанной мною ранее причине. Если это все сделать в одном пакете, то будет
Код: plaintext
1.
2.
3.
parent
Child
Child
Если перенести класс с Main в один пакет с классом Child, то опять-таки закоментированные строки не работают. По той же причине.
...
Рейтинг: 0 / 0
Убейте
    #34082892
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
теперь я в тупике
На момент компиляции известно что в ссылке Parent p хранится объект типа Parent, с чего же вдруг нельзя вызвать его собственный метод?! да хоть private!
...
Рейтинг: 0 / 0
Убейте
    #34083398
Ноль2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
to Fjord and Leonidv
Еще одна моя глупость и все
Компилирую свои package1 и package2, только в package1 метод v() - public
Потом компилирую package1, изменив предварительно метод v() на protected

Теперь
Код: plaintext
1.
2.
3.
4.
5.
6.
 package  package2;
 public   class  Class2  extends  package1.Class1 {
	 public   void  v(){}	
	 public   static   void  main(String[] args){
         package1.Class1 c =  new  Class2();
         c.v(); ...
работает без проблем
Делаю скорее всего неправильный вывод, что javac колбасит что-то не то???
Прокомментируйте, bitte
С Уважением и Благодарностью ко всем за все ранее сказанное
...
Рейтинг: 0 / 0
Убейте
    #34083631
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забавный глюк. Среда показывает ошибку но сомпилятор не возмущается и делает свое дело как будто метод в первом классе public, и билдит и запускает без проблем. Думал что может ява машина что нить кеширует, но после перезапуска компа ничего не изменилось. После удаления готовых классов и жара сомпилятор выдал долгожданную ошибку. В книжке все четко описанно, что работать не должно. Почему так незнаю. Очень интересно самому.
...
Рейтинг: 0 / 0
Убейте
    #34083717
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кажется понял: ошибка при protected v() должна быть (обязанна), и class2.class само собой не появится, а если v() сделать на время протектед и потом компилить и запускать то
Код: plaintext
Package2.Class1 c =  new  Class2();
будет в силе, и ошибки при компиляции не возникнет. забавно.
Наверняка я не прав. Очень интересно. Может кто нибудь в силах прояснить ситуацию?
...
Рейтинг: 0 / 0
Убейте
    #34083727
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fjordкажется понял: ошибка при protected v() должна быть (обязанна), и class2.class само собой не появится, а если v() сделать на время протектед и потом компилить и запускать то
Код: plaintext
Package2.Class1 c =  new  Class2();
будет в силе, и ошибки при компиляции не возникнет. забавно.
Наверняка я не прав. Очень интересно. Может кто нибудь в силах прояснить ситуацию?
там
Код: plaintext
Package1.Class1 c =  new  Class2();
конечно, это я эксперементировал
...
Рейтинг: 0 / 0
Убейте
    #34084000
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Развиваем тему даже если не переопределять метод v в классе 2, а просто вызываем метод родителя, компилируем все, потом изменяем в классе 1 доступ к методу на private, и перекомпилируем только класс 1, то один фиг объект класса 2 спокойно запускает private метод родителя!
А вот это уже конкретный глюк.
...
Рейтинг: 0 / 0
Убейте
    #34084139
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
     protected   void  v(){System.out.println ("Вызван метод родителя");}
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 package  package2;
 public   class  Class2  extends  package1.Class1 {
     public   static   void  main(String[] args){
        package1.Class1 c =  new  Class2();
        c.v();     
    }
}

Компилируем оба класса.
Меняем в классе 1 доступ к методу на приват.
Компилируем только первый класс.
Запускаем.
Все работает.

Комментарии?
...
Рейтинг: 0 / 0
Убейте
    #34084292
fjord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2АСУ ТПшник
Все так, но при надобности изменить и откомпилировать второй класс ничего невыйдет, придется лезть в первый и опять делать его паблик. Поидее все нормально, при защищенном певом классе оба класса сразу нельзя будет откомпилировать. Поэтому нужно создавать сперва классы с протектед методами и полями а потом те которые будут ими пользоваться.
...
Рейтинг: 0 / 0
Убейте
    #34084471
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот кто то уже это дело и до нас обнаружил
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4298813
на другом форуме говорят, что в 1.6 наконец это исправили.
...
Рейтинг: 0 / 0
25 сообщений из 55, страница 1 из 3
Форумы / Java [игнор отключен] [закрыт для гостей] / Убейте
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]