Java 类和对象中经典问题

这块也不知道该怎么总结,感觉很多,但又不知道总结什么。可能高手到一定境界无招胜有招吧,哈哈,自吹了。

总结自己觉得比较出问题或者之前面试中影响比较深刻的内容吧。

访问修饰符public,private,protected,以及不写(默认)时的区别?

修饰符 当前类 同包内 子类 其他类
private - - -
default - -
protected -
public

关于静态代码块、代码块、构造函数的执行顺序问题

public class Father {
    static {
        System.out.println("Father static");
    }
    {
        System.out.println("Father {}");
    }
    public Father() {
        System.out.println("Father()");
    }
}

public class Son extends Father {
    static {
        System.out.println("Son static");
    }
    {
        System.out.println("Son {}");
    }
    public Son() {
        System.out.println("Son()");
    }
    public static void main(String[] args) {
        Son son = new Son();
    }
}

打印结果:

输入图片说明

重写和重载

重载是同一个类中,而重写存在于子父类中。

满足条件:

重写

首先子类修饰符可见范围不能小于父类,返回值类型需要相同,方法名相同,方法的参数类型、个数、顺序需要相同,当然参数名允许不同。

重载

方法名必须相同,方法参数的类型、个数或者顺序不能相同。注意:返回值类型不同(特别注意:返回值类型可以是父类返回值类型的子类),其他相同不能构成重载。

    public void sayHello(String name, Date time) {
        System.out.println("hello " + name + ",现在是" + time);
    }

    // 特别注意:
    // 返回值类型不同是无法工程重载
    public Date sayHello(String name, Date time) {
        System.out.println("hello " + name + ",现在是" + time);
        return time;
    }

    // 参数顺序不同
    public void sayHello(Date time, String name) {
        System.out.println("hello " + name + ",现在是" + time);
    }
    
    // 参数个数不同
    public void sayHello(String name) {
        System.out.println("hello " + name);
    }

    // 参数类型不同
    public void sayHello(String name, String context) {
        System.out.println("hello " + name + "," + context);
    }

final修饰的类、函数、变量的特点

  • final修饰的类不能被继承
  • final修饰的函数不能被重写
  • final修饰的变量的引用不能被修改,但能修改该引用的内容
    private final List<String> list = new ArrayList<String>();
    
    // 特别注意:
    // 错误的修改final修饰变量的引用
    list = new ArrayList<String>();
    
    // 可以修改引用的内容
    public void test() {
        list.add("A");
    }

如何实现equals方法

public class Student {

    // 为了代码简约和正确性,不考虑对状态的封装
    public String name;
    public int age;

    @Override
    public boolean equals(Object o) {
        // 1. 判断引用的对象是否相同,相同则为相等
        if (this == o) return true;

        // 2. 判断传入对象是否为空,因为调用equals的对象肯定不为空,如果object为空,则肯定不等
        //    判断传入对象和this对象是否为同一个类构建的对象,如果不是,则肯定不等
        if (o == null || getClass() != o.getClass()) return false;

        // 3. 如果是同一个类构建的对象,则可以转型为相同类的对象,方便观察其状态是否相同
        Student student = (Student) o;

        // 4. 观察状态是否相同。如果是基本数据类型,简单粗暴的使用== 。如果是对象,则还需要使用equals方法判断
        if (age != student.age) return false;
        return name.equals(student.name);

    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

equals方法和hascode方法的关系

  • 如果两个对象调用equals返回true,则他们的hascode必须相同
  • 如果两个对象的hascode相同,并不能说明这两个对象equals

猜你喜欢

转载自my.oschina.net/u/2930289/blog/1594301