oop
object oriented programming in java
interface inheritance
There is hierarchy(等级差异) between class and class.
For example, SLList and AList are two type of List with different data organizing way.
They are hyponyms of List and List is hypernyms of them. We also called this relationship as subclass and superclass.
In java, the superclass is used to provide interface, and the subclass to provide implementation.
Here is an example
public interface List<Item>{...}
public AList<Item> implements List<Item> {...}
//this implements is a promise that we will cover all
//attributes and behaviors in the List<Item>
Inheritance and the function overriding, we solve many problems of function overload. We don't need to give each subclass a overloaded function.
Note: we don't need to write the "public" or "private" in interface.
overriding
When we are implementing these functions, we'd better note here @override
Inheritance can be multi-generational. One superclass may also is subclass of another class.
default
Sometime, we don't want the superclass only contians the interface, we hope it can complete some implementations.
public interface List<Item>{
...
default public void print(){
for(int i=0;i<size();i++){
System.out.print(get(i)+" ");
}
System.out.println();
}
}
For every subclass of List
We will use this function.
For SLList, this default function is obviously an awful solution, so it can make its own implementation, and system
will use its method instead of default one.
upcast and compile time type check
We have talked about the rule of equals(a=b) in java, which is the copy the bits from b to a.
Now, we refer to the superclass and subclass. Like below
public interface List<Item>{...}
public AList<Item> implements List<Item> {...}
...
public static void func(List<int> list);
...
Alist<int> list;
func(list); //what happened in the argument passing
Or we just use a more simple example
While compiling, system will check "is-a" relationship. In the example above, the AList is a List, so this sentence is right.
However, if we swap their positions, List isn't an AList, and it will occur mistake.
dynamic method selection
We still talk about the example below
List
Besides, we actually create a AList object, and list points at an AList object. So AList
The dynamic type of the object can be changed, it can turned from AList to SLList. When program runs the overidden method, it will find the appropriate method in the dynamic type.
overload of inheritance
We have known that Java select the overloaded functions by type of parameter we give.
In fact, it will check the static type instead of dynamic type. Here we give an example
//overloaded function
public static void func(List<Integer> list);
public static void func(SLList<Integer> list);
...
//in the main function
SLList<Integer> a=new SLList<>(); //static type is SLList and dynamic type is SLList too
List<Interger> b=a; //static type is List and dynamic type is SLList
func(a); //use the second one
func(b); //use the first one
extends and implement
We have discussed the implementation relationship, which asks the subclass should implement all of methods the superclass
provides.
However, sometimes we want to add more methods in the subclass, and in this situation we will use the keyword extends .
In this example above, RotatingSLList will inherit all methods the SLList has and can make modifications or add some methods.
And we need to know what exactly do we inherit by extending.
- All instances and static variables
- All methods
- All nested class
But we should notice that the constructor isn't inherited and we can't access the private members directly in subclass.
The situation of constructor is a little special. For ensuring "is-a" relationship, we promise that we need to use the superclass's
constructor at first in the subclass's constructor. For example
public class VengefulSLList<Item> extends SLList<Item>{
SLList<Item> deletedItems;
...
public VengefulSLList(){
super();
deletedItems = new SLList<Item>();
}
...
}
This "super()" is explicitly using the constructor of superclass, if we don't use it, the Java will automatically call the superclass's
non-argument constructor for us. If we need to pass some arguments to the superclass's constructor, it must be use explicitly.
Note: you can implement multiple interface like that public class ArrayDeque<T> implements Deque<T>,Iteratable<T>
the object class
Every class in Java is descendant of Object class, or extends the Object class.
They may don't explicitly express the relationship with Object but they actually do it.
So, we want to know what we actually inherit from the Object class.
Object method
toString()
The default method of toString() is to print the location of the object in memory. For most of class we define by ourselves, we should write our own toString() function to make the print result readable.
We note that the method System.out.print()
will call the toString() method for all of argument and print the string.
I will implement the toString() method in my ArreySet.java class. You can find this file in the JavaTest file.
equals()
We already have the "A==B" in Java and it will compare each bit in A and B. For the primitive variable it will compare their value and for the reference variable it will compare their address.
public class test{
private int a;
private int b;
public test(int a,int b){...}
...
}
...
//main
test A=test(1,2);
test B=test(1,2);
//However, A==B is false
For reference type variable, "==" means they point at the same object rather the objects have the same content.
So we need to have equals() method.
static type and dynamic type
****This part note is not organized well, I will rewrite it after.
When we call the method, we will turn to dynamic type. It is what we have discussed before. However, static type will also make
the difference.
In fact, a object, whose static type is superclass and dyanmic type is subclass which make extends, it can't call the method
its dynamic type added.
And when we don't call the method, the object always express as its static type.
All in all, static type is its type and decide what the object can do, meanwhile the dynamic type decide what the object actually do.
higher order function
How to create a function variable.
We can create the interface to make it possible. (类似于cpp的仿函数)
//定义
public interface IntUnaryFunction {
int apply(int x);
}
//实现
public class TenX implements IntUnaryFunction {
/* Returns ten times the argument. */
public int apply(int x) {
return 10 * x;
}
}
//函数使用
public static int do_twice(IntUnaryFunction f, int x) {
return f.apply(f.apply(x));
}
//实际调用
System.out.println(do_twice(new TenX(), 2));
polymorphism
The main idea of polymorphism is "many methods". And polymorphism express that an object can be an instance of its own class, its superclass and its superclass's superclass...
Java's alternative for operator overloading
introduction
In cpp, we can write one function to find the max element in an array easily, as long as the elements in the array have operator overload about the '>', '<' and '=='. Luckily, for most of the class that is comparable, coders will provide the operator overloading functions. This one function can cover most of situations.
However, in Java, we can't make operator overloading, so things will become a little complex.
At first, we want to write a compare function in each class to replace the ability of operator overloading, but it means all of class should coincidentally use the same compare function name. So the good way is to write an interface and let each class to implement it.
All class that is comparable should implement this interface, and provide the compareTo function.
Comparable
In fact, Java has already provided a similar interface for us and it has been used in countless Java library
public interface Comparable<T>{
public int compareTo(T obj);
}
...
//an example to implement the generic interface
public class Dog implements Comparable<Dog>{
...
public int compareTo(Dog anoDog){
...
}
}
In this real, built-in interface, we find it uses generic and it can avoid some awful cast from Object to each class.
Comparator
Sometimes, an object may have many dimensions to compare, but it can only have one compareTo function if we only use the Comparable interface. So Java also offers us another interface.
The usual way to use the comparator is different from the comparable, we will create a static nested class in the class we want to make compare.
public class Dog implements Comparable<Dog>{
...
private static class NameCompare implements Comparator<Dog>{
public int compare(Dog dog1,Dog dog2){
return dog1.name.compareTo(dog2.name);
}
}
...
}
We note that the nested class is private here, which means it can't be instanced outside.
So, in Java's generic programming we should avoid using > < = and we should use the compareTo() equals() method.