«Slicing» - это то, где вы назначаете объект производного класса экземпляру базового класса, тем самым теряя часть информации - часть его «нарезана».
Например,
class A {
int foo;
};
class B : public A {
int bar;
};
Итак, объект типа B
имеет два элемента данных: foo
и bar
.
Тогда, если вы должны были написать это:
B b;
A a = b;
Затем информация в b
о члене bar
теряется в a
.
Что здесь происходит?
blockquote>Вы неправильно поняли значение
protected
. Вы можете получить доступ к защищенным членам, объявленным вA
, изC
, но только для экземпляровC
или подклассовC
. Подробнее о защищенном доступе см. В разделе 6.6.2 раздела JLS . В частности:Пусть C - класс, в котором объявлен защищенный член. Доступ разрешен только внутри тела подкласса S из C.
Кроме того, если Id обозначает поле экземпляра или метод экземпляра, то:
blockquote>
- [... ]
- Если доступ осуществляется с помощью выражения доступа к полю E.Id, где E является первичным выражением или выражением вызова метода E.Id (...), где E является первичным выражением, то доступ разрешен тогда и только тогда, когда тип E является S или подклассом S.
(Emphasis mine.)
Итак этот код был бы точным:
C c = new C(); System.out.println(c.publicInt); System.out.println(c.protectedInt);
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
Когда вы делаете A a = new A();
и a.protectedInt
, вы пытаетесь получить доступ к защищенному члену A, который является незаконным в соответствии со стандартами java
. Вместо этого вы можете делать this.protectedInt
напрямую.
Защищенные средства:
a) Этот член будет доступен для всех классов в одном пакете с помощью ссылки объекта.
b) Для другого пакета это будет доступно только внутри Подклассы A говорят B и используемая ссылка могут быть экземплярами B или любого подкласса B.
Возьмем пример:
Пусть A - родительский класс в некотором пакете, скажем com.ex1
Пусть B, C - классы в разных пакетах по A say com.ex2
. Кроме того, B extends A
и C extends B
. Мы увидим, как мы можем использовать защищенное поле A внутри B (подкласс A)
Код A:
public class A {
protected int a = 10;
}
Код B:
public class B extends A {
public void printUsingInheritance() {
// Using this
System.out.println(this.a);
}
public void printUsingInstantiation() {
// Using instance of B
B b = new B();
System.out.println(b.a);
// Using instance of C as C is subclass of B
C c = new C();
System.out.println(c.a);
A a = new A();
System.out.println(a.a); // Compilation error as A is not subclass of B
}
}
Код C:
public class C extends B {
}
Для защищенных статических:
Те же правила применяются, за исключением того, что в b) теперь он доступен в любом подклассе класса A по ссылке класса A. [Д0] Ссылка
В том же пакете, где объявлен защищенный член, разрешен доступ:
package package1;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // got printed
C c = new C();
System.out.println(c.protectedInt); // got printed as well
}
}
Вне пакета, в котором объявлен защищенный член, доступ разрешен тогда и только тогда, когда по коду, который отвечает для реализации этого объекта. В этом случае C отвечает за реализацию этого объекта, поэтому он может получить доступ к защищенным.
package package2;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // compiler complains
C c = new C();
System.out.println(c.protectedInt); // got printed
}
}
Поскольку C
наследует A
, C
может напрямую использовать переменную protected
в A
, как показано ниже
public class C extends A{
public void go(){
System.out.println(protectedInt);
}
}
. В соответствии с вашим кодом вы создаете экземпляр из A
и доступа к protected
переменной через этот экземпляр , который нарушает правило java. Защищенная переменная не видна вне пакета
A
, который находится в другом пакете с классом C
, который является тем, что «реализует». объект типа C
.
– Jon Skeet
2 September 2013 в 19:11
protected
, нет - если бы это была видимость по умолчанию (пакет) илиprivate
, это было бы не видно. – Jon Skeet 2 September 2013 в 14:34E
здесьA
, аS
-C
. ХотяC
является подклассомA
,A
не является i> подклассомC
. – Jon Skeet 2 September 2013 в 17:49