Part 3
Името на метода + типовете на неговите аргументи
Възможност да дефинираме няколко пъти метод с едно и също име, но различна сигнатура
Възможността да имаме променлива от един тип, но имплементация от различен.
Нещо, което може да съдържа само дефиниции на публични методи.
Не. Няма и да има смисъл.
Да. Това е важно за полиморфизмът.
Това решава много фундаментален проблем.
...
ArrayList<Integer> ns = new ArrayList<>();
ArrayList<Person> people = new ArrayList<>();
public class Box<T> {
private T data;
public Box(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
Box<Integer> intBox = new Box<Integer>(5);
Box<Panda> pandaBox = new Box<Panda>(5);
Ползват се навсякъде, особено в Collections framework-а
public class Person {
public String name;
public String age;
}
ArrayList<Person> people = new ArrayList<>();
Collections.sort(people); // ?
public class Person implements Comperable<Person> {
public String name;
public String age;
public int compareTo(Person other) {
if(this.age == other.age) { return 1; }
if(this.age < other.age) { return -1; }
return 1;
}
}
public static void iAcceptEverything(Object obj) {
System.out.println(obj.toString());
}
SomeClass.iAcceptEverything(5);
SomeClass.iAcceptEverything("asdf");
SomeClass.iAcceptEverything(true);
SomeClass.iAcceptEverything(new Panda());
public class SomeClass {
public static void printArray(Object[] arr) {
StringBuilder b = new StringBuilder();
b.append("[");
for (int i = 0; i < arr.length; i++) {
Object o = arr[i];
b.append(o.toString());
if (i != arr.length - 1) {
b.append(", ");
}
}
b.append("]");
System.out.println(b.toString());
}
}
// this is not working, because of the primitive types
int[] a = {1, 2, 3};
SomeClass.printArray(a);
// this works well
Integer[] a = {1, 2, 3};
SomeClass.printArray(a);
public class Entity {
private String identifier;
public String getIdentifier() {
return identifier;
}
public Entity(String identifier) {
this.identifier = identifier;
}
}
public class Student extends Entity {
public Student(String identifier) {
super(identifier);
}
}
public class Student extends Entity {
public Student(String identifier) {
super(identifier);
}
}
public class Student extends Entity {
public Student(String identifier) {
super(identifier);
}
}
public class Student extends Entity {
private String name;
public Student(String identifier) {
super(identifier);
}
public Student(String identifier, String name) {
this(identifier);
this.name = name;
}
}
Entity ent = new Student("1", "Ivo");
Имаме същият ефект както при интерфейсите.
public class A extends B implements C, D {
...
}
// Всичко това е възможно
A a = new A();
B a1 = new A();
C a2 = new A();
D a3 = new A()
public class E extends A {
...
}
// Всичко това е възможно
E e = new E();
A e1 = new E();
B e2 = new E();
C e3 = new E();
D e4 = new E();
public abstract class Runner {
protected String result;
protected String code;
protected String test;
public Runner(String code, String test) {
this.code = code;
this.test = test;
}
public String run() {
lint();
compile();
execute();
return result;
}
public abstract void lint();
public abstract void compile();
public abstract void execute();
}
public class PythonRunner extends Runner {
public PythonRunner(String code, String test) {
super(code, test);
}
public void lint() {}
public void compile() {}
public void execute() {
result = "OK";
}
}
public class RealPythonRunner extends PythonRunner {
public RealPythonRunner(String code, String test) {
super(code, test);
}
@Override
public void execute() {
super.execute();
result = "NOT OK";
}
}