PECS (производитель extends
и потребитель super
)
Мнемоника → принцип Get и Put.
Этот принцип гласит, что:
В Java параметры и параметры типового типа не поддерживают наследование следующим образом.
class Super {
void testCoVariance(Object parameter){} // method Consumes the Object
Object testContraVariance(){ return null;} //method Produces the Object
}
class Sub extends Super {
@Override
void testCoVariance(String parameter){} //doesn't support eventhough String is subtype of Object
@Override
String testContraVariance(){ return null;} //compiles successfully i.e. return type is don't care
}
Принцип подстановки Лискова: Массивы являются ковариантными (небезопасными), но Generics не являются, то есть инвариантными (безопасными). Принцип подстановки не работает с параметризованными типами, что означает, что это незаконно писать. Ковариант просто означает, что X
является подтипом Y
, тогда X[]
также будет подтипом Y[]
.
Object name= new String("prem"); //works
List numbers = new ArrayList();//gets compile time error
Integer[] myInts = {1,2,3,4};
Number[] myNumber = myInts;
myNumber[0] = 3.14; //attempt of heap pollution i.e. at runtime gets java.lang.ArrayStoreException: java.lang.Double(we can fool compiler but not run-time)
List list=new ArrayList<>();
list.add("prem");
List
ограниченный (т. е. заголовок к чему-либо) подстановочный знак: Есть 3 разных варианта подстановочных знаков:
?
или ? extends Object
- неограниченный подстановочный знак. Он обозначает семью всех типов. Использовать, когда вы оба получаете и ставите. ? extends T
(семейство всех типов, которые являются подтипами T
) - подстановочный знак с верхней границей. T
является самым верхним классом в иерархии наследования. Используйте подстановочный знак extends
, когда вы получаете только значения из структуры. ? super T
(семейство всех типов, которые являются супертипами T
) - подстановочный знак с нижней границей. T
является самым низким классом в иерархии наследования. Используйте подстановочный символ super
, если вы только поместите значения в структуру. Примечание: подстановочный знак ?
означает ноль или один раз, представляет неизвестный тип. Подстановочный знак может использоваться как тип параметра, никогда не используемый в качестве аргумента типа для вызова общего метода, создания экземпляра универсального класса (т. Е. При использовании подстановочного знака, эта ссылка не используется в другом месте программы, как мы используем T
).
class Shape { void draw() {}}
class Circle extends Shape {void draw() {}}
class Square extends Shape {void draw() {}}
class Rectangle extends Shape {void draw() {}}
public class TestContraVariance {
/*
* Example for an upper bound wildcard (Get values i.e Producer `extends`)
*
* */
public void testCoVariance(List extends Shape> list) {
list.add(new Shape()); // Error: is not applicable for the arguments (Shape) i.e. inheritance is not supporting
list.add(new Circle()); // Error: is not applicable for the arguments (Circle) i.e. inheritance is not supporting
list.add(new Square()); // Error: is not applicable for the arguments (Square) i.e. inheritance is not supporting
list.add(new Rectangle()); // Error: is not applicable for the arguments (Rectangle) i.e. inheritance is not supporting
Shape shape= list.get(0);//compiles so list act as produces only
/*You can't add a Shape,Circle,Square,Rectangle to a List extends Shape>
* You can get an object and know that it will be an Shape
*/
}
/*
* Example for a lower bound wildcard (Put values i.e Consumer`super`)
* */
public void testContraVariance(List super Shape> list) {
list.add(new Shape());//compiles i.e. inheritance is supporting
list.add(new Circle());//compiles i.e. inheritance is supporting
list.add(new Square());//compiles i.e. inheritance is supporting
list.add(new Rectangle());//compiles i.e. inheritance is supporting
Shape shape= list.get(0); // Error: Type mismatch, so list acts only as consumer
Object object= list.get(0); // gets an object, but we don't know what kind of Object it is.
/*You can add a Shape,Circle,Square,Rectangle to a List extends Shape>
* You can't get an Shape(but can get Object) and don't know what kind of Shape it is.
*/
}
}
Вам нужно ввести код трубы, если __name__ == '__main__' part. ( Почему? ) И измените p2.recv на p1.recv
import multiprocessing
def ProcessCreator(pipe):
pipe.send("hello from other process")
if __name__ == "__main__":
multiprocessing.freeze_support()
p1, p2 = multiprocessing.Pipe()
proc = multiprocessing.Process(target = ProcessCreator, args = (p2,))
proc.start()
print p1.recv()