方法的重载与重写

  1. 二者的定义细节: 略
  2. 从编译和运行的角度看:
    重载,是指允许存在多个同名方法,而这些方法的参数不同。 编译器根据方法不同的参数表, 对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。 它们的调用地址在编译期就绑定了。 Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。

所以: 对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定” ;而对于多态,只有等到方法调用的那一刻, 解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定” 。
引用一句Bruce Eckel的话: “不要犯傻,如果它不是晚绑定, 它就不是多态。”

多态是运行时行为还是编译时行为

答:运行时行为

  1. package stu.zdkk.java2;
  2. import java.util.Random;
  3. //面试题:多态是编译时行为还是运行时行为?
  4. //证明如下:
  5. class Animal {
  6. protected void eat() {
  7. System.out.println("animal eat food");
  8. }
  9. }
  10. class Cat extends Animal {
  11. protected void eat() {
  12. System.out.println("cat eat fish");
  13. }
  14. }
  15. class Dog extends Animal {
  16. public void eat() {
  17. System.out.println("Dog eat bone");
  18. }
  19. }
  20. class Sheep extends Animal {
  21. public void eat() {
  22. System.out.println("Sheep eat grass");
  23. }
  24. }
  25. public class InterviewTest {
  26. public static Animal getInstance(int key) {
  27. switch (key) {
  28. case 0:
  29. return new Cat ();
  30. case 1:
  31. return new Dog ();
  32. default:
  33. return new Sheep ();
  34. }
  35. }
  36. public static void main(String[] args) {
  37. int key = new Random().nextInt(3);
  38. System.out.println(key);
  39. Animal animal = getInstance(key);
  40. animal.eat();
  41. }
  42. }

image.pngimage.png

  1. package stu.zdkk.java2;
  2. //考查多态的笔试题目:
  3. public class InterviewTest1 {
  4. public static void main(String[] args) {
  5. Base base = new Sub();
  6. base.add(1, 2, 3);
  7. // Sub s = (Sub)base;
  8. // s.add(1,2,3);
  9. }
  10. }
  11. class Base {
  12. public void add(int a, int... arr) {
  13. System.out.println("base");
  14. }
  15. }
  16. class Sub extends Base {
  17. public void add(int a, int[] arr) {
  18. System.out.println("sub_1");
  19. }
  20. // public void add(int a, int b, int c) {
  21. // System.out.println("sub_2");
  22. // }
  23. }

image.png

这显然能说明多态是运行时行为,因为在编译时编译器并不认为Sub重写了Base的add方法,但是在运行时打印了Sub的add方法输出语句,说明在运行时Sub的add方法构成了对Base类add方法的重写,因此才打印”sub_1”

==和equals的区别

  1. == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型
    就是比较内存地址
  2. equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也
    是==;我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中
    用的比较多,久而久之,形成了equals是比较值的错误观点。
  3. 具体要看自定义类里有没有重写Object的equals方法来判断。
  4. 通常情况下,重写equals方法,会比较类中的相应属性是否都相等