Anson Zhang
Published on 2025-02-14 / 34 Visits
0
0

AP计算机A易错知识点

错误知识点大致分类为:

  1. Polymorphism

  2. Inheritance

  3. Operations

  4. Array & ArrayList

Polymorphism

flowchart TD subgraph CT["Compile-time Polymorphism"] A["Method Call"] --> B["Compiler checks method signature"] B --> C["Binds to specific method"] C --> D["Binding done at compile time"] end subgraph RT["Run-time Polymorphism"] E["Method Call"] --> F["JVM checks object type"] F --> G["Determines actual method"] G --> H["Binding done at runtime"] end style CT fill:#e6f3ff,stroke:#333 style RT fill:#fff0e6,stroke:#333

Compile-Time Polymorphism

  • Overloading

  • Requirements

    1. Must have the same method name

    2. Must have different parameter lists

      1. Number of parameters

      2. Types of parameters

      3. Order of parameter types

    3. 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

    1. Constructor methods cannot be overridden

    2. Method must be inherited (not private) to be overridden

    3. Must have the same name as the parent method

    4. 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 by Parent object = new Child(); will use the Parent method (determined by reference type)

  • Calling a overriding method from an object declared by Parent object = new Child(); will use the Child 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 -> 1

  • double x = 3 / 2 -> 1.0

  • double x = (double) 3 / 2 -> 3.0 / 2 -> 1.5

  • double x = 3 / (double) 2 -> 1.5

  • double 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


Comment