错误知识点大致分类为:
Polymorphism
Inheritance
Operations
Array & ArrayList
Polymorphism
Compile-Time Polymorphism
Overloading
Requirements
Must have the same method name
Must have different parameter lists
Number of parameters
Types of parameters
Order of parameter types
Return type alone is NOT enough to distinguish overloaded methods
public class Class {
public void function() {
//some code
}
// effective overloading example 1:
public void function(int x) {
//some code
}
// ineffective overloading example 1:
public void function1() { // different function name
//some code
}
// ineffective overloading example 2:
public int function() { // even though the return type is changed, it is ineffective (see point 3)
//some code
}
}
Run-Time Polymorphism
Overriding
Requirements
Constructor methods cannot be overridden
Method must be inherited (not private) to be overridden
Must have the same name as the parent method
Must have the same parameter list (same number of parameters, same parameter type) as the parent method
class Parent {
void method(String s) { }
}
class Child extends Parent {
// Effective overriding - same parameter type, same number of parameters, same method name
void method(String s) { }
// Not overriding - different parameter type
void method(Object o) { }
// Not overriding - different method name
void Method(String s) { }
// Not overriding - different number of parameters
void method(String s, int i) { }
}
Inheritance
Mistake 1: Default Constructors
If the parent class doesn't have default constructor, implicit super doesn't work!!!
Parent's constructors are not inherited
class Parent {
private String name;
// Parent constructor
public Parent(String name) {
this.name = name;
}
}
class Child extends Parent {
// WRONG: No explicit super call
public Child() { // Compilation error
// Implicit super() doesn't work as Parent needs a parameter
}
// CORRECT:
public Child() {
super("default name"); // The default constructor for child as to pass a string through the super() method
}
}
Mistake 2: Calling Methods
Calling a
static
method from an object declared byParent object = new Child();
will use theParent
method (determined by reference type)Calling a overriding method from an object declared by
Parent object = new Child();
will use theChild
method (determined by object)
class Parent {
static void staticMethod() {
System.out.println("Parent static");
}
}
class Child extends Parent {
// This is method HIDING, not overriding!
static void staticMethod() {
System.out.println("Child static");
}
}
Parent p = new Child();
p.staticMethod(); // Prints "Parent static" - determined by reference type!
注:若static method使用overriding,则是method hiding。
class Parent {
void instanceMethod() {
System.out.println("Parent instance");
}
}
class Child extends Parent {
@Override
void instanceMethod() {
System.out.println("Child instance");
}
}
// Usage
Parent p = new Child();
p.instanceMethod(); // Prints "Child instance" - determined by object type!java
Other Things to Remember
you can put child objects in place of parent objects
public class Parent {
// Some code here
}
public class Child extends Parent {
// Some code here
}
// Usage
ArrayList<Parent> arrayList = new ArrayList<Parent>();
Parent parent = new Parent();
Child child = new Child();
arrayList.add(parent);
arrayList.add(child); // The object "Child" can also be added into the ArrayList
you can explicitly cast child objects into parent objects
public class Parent {
// Some code here
}
public class Child extends Parent {
// Some code here
}
Child child = new Child();
Parent parent = (Parent) child; // The "child" object is casted into a parent object
Operations
Casting
downcast - explicit - lose information
upcast - automatic - doesn't lose information
Mistakes in Division
int x = 3 / 2
-> 1double x = 3 / 2
-> 1.0double x = (double) 3 / 2
-> 3.0 / 2 -> 1.5double x = 3 / (double) 2
-> 1.5double x = (double) (3 / 2)
-> 1.0这里
(double)
cast的是后面括号内的整体,也就是已经变成1的3 / 2
,所以就变成了(double) 1
,结果也就是1.0。
Array & ArrayList
Iteration
1. For-Each Loop
The for-each loop cannot modify the original collection!!!
2. "0 to End" Loop
Beware of the boundaries!!!
Beware of what to use as the end!!!
Array:
array.length;
(no parentheses)!!!String:
s.length();
(parentheses)!!!ArrayList:
arrayList.size();
Beware that
i
is incremented!!!
for (int i = 0; i < array.length; i++) { System.out.println(array[i]; } // correct iteration
for (int i = 0; i <= array.length; i++) { System.out.println(array[i]; } // run-time error: index out of bounds
for (int i = 0; i <= array.length - 1; i++) { System.out.println(array[i]; } // correct iteration
3. "End to 0" Loop
Beware of the boundaries!!!
Beware of what to use as the start
Array:
array.length - 1;
(remember the -1)!!!String:
s.length() - 1;
(remember the -1)!!!ArrayList:
arrayList.size() - 1;
(remember the -1)!!!
Beware that it ends at
>= 0
!!!Beware that
i
is decremented!!!
for (int i = array.length - 1; i >= 0; i--) { System.out.println(array[i]; } // correct iteration
for (int i = array.length; i >= 0; i--) { System.out.println(array[i]; } // run-time error: index out of bounds
for (int i = array.length - 1; i > 0; i--) { System.out.println(array[i]; } // index 0 is not iterated
for (int i = array.length - 1; i >= 0; i++) { System.out.println(array[i]; } // infinite loop since i is incremented and not decremented