写点什么

15 道类和对象面试题,快看看自己会几道

用户头像
田维常
关注
发布于: 2021 年 01 月 29 日

1.类与对象有哪些区别?


类是一个抽象的概念,是对某一事物的描述;而对象是类的实例,是实实在在存在的个体。


比如:“男人”就是一个类(一个概念),而老田(田维常)就是实实在在的一个“对象”。


注意:对象中又有类对象,即 Class 对象,但是类对象始终还是对象,不是类,这两个概念别搞混淆了。


2.Java 中可以多继承吗?


Java 中只能单继承,但可以实现多接口,并且支持多层继承。


3.Java 中为什么不能实现多继承?


答:从技术的实现角度来说,是为了降低编程的复杂性。假设 A 类中有一个 m() 方法,B 类中也有一个 m() 方法,如果 C 类同时继承 A 类和 B 类,那调用 C 类的 m() 方法时就会产生歧义,这无疑增加了程序开发的复杂性,为了避免这种问题的产生,Java 语言规定不能多继承类,但可以实现多接口。


4.覆盖和重载有哪些区别?


  • 重写(Override)从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。


public class Father {
public static void main(String[] args) { // TODO Auto-generated method stub Son s = new Son(); s.sayHello(); }
public void sayHello() { System.out.println("Hello"); }}
class Son extends Father{
@Override public void sayHello() { // TODO Auto-generated method stub System.out.println("hello by "); }
}
复制代码


重写 总结:


1.发生在父类与子类之间


2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同


3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)


4.重写方法一定不能抛出新的检查异常或者比被重写方法的更加宽泛的检查型异常


  • 重载(Overload)在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。


public class Father {
public static void main(String[] args) { // TODO Auto-generated method stub Father s = new Father(); s.sayHello(); s.sayHello("wintershii");
}
public void sayHello() { System.out.println("Hello"); }
public void sayHello(String name) { System.out.println("Hello" + " " + name); }}
复制代码


重载 总结:1.重载 Overload 是一个类中多态性的一种表现 2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序) 3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。


5.为什么方法不能根据返回类型来区分重载?


答:因为在方法调用时,如果不指定类型信息,编译器就不知道你要调用哪个方法了。比如,以下代码:


float max(int x,int y);int max(int x,int y);// 方法调用max(1,2);
复制代码


因为 max(1,2) 没有指定返回值,编译器就不知道要调用哪个方法了。


6.说说构造方法的特点有哪些?


答:构造方法的特征如下:


  • 构造方法必须与类名相同;

  • 构造方法没有返回类型(默认返回本类类型);

  • 构造方法不能被继承、覆盖、直接调用;

  • 类定义时提供了默认的无参构造方法;

  • 构造方法可以私有,外部无法使用私有构造方法创建对象。


构造函数能不能被覆盖?能不能被重载?


构造函数可以重载,但不能覆盖。


7.以下程序执行的结果是?


class ExecTest {    public static void main(String[] args) {        Son son = new Son();    }}class Parent{    {        System.out.print("1");    }    static{        System.out.print("2");    }    public Parent(){        System.out.print("3");    }}class Son extends Parent{    {        System.out.print("4");    }    static{        System.out.print("5");    }    public Son(){        System.out.print("6");    }}
复制代码


结果是:251346


8.类加载顺序


整体



细分



以下程序执行的结果是?


class A {    public int x = 0;    public static int y = 0;    public void m() {        System.out.print("A");    }}class B extends A {    public int x = 1;    public static int y = 2;    public void m() {        System.out.print("B");    }    public static void main(String[] args) {        A myClass = new B();        System.out.print(myClass.x);        System.out.print(myClass.y);        myClass.m();    }}
复制代码


结果是:00B


注意:在 Java 语言中,变量不能被重写。


9.Java 中的 this 和 super 有哪些区别?


this 和 super 都是 Java 中的关键字,起指代作用,在构造方法中必须出现在第一行,它们的区别如下。


  • 基础概念:this 是访问本类实例属性或方法;super 是子类访问父类中的属性或方法。

  • 查找范围:this 先查本类,没有的话再查父类;super 直接访问父类。

  • 使用:this 单独使用时,表示当前对象;super 在子类覆盖父类方法时,访问父类同名方法。


10.在静态方法中可以使用 this 或 super 吗?为什么?


在静态方法中不能使用 this 或 super,因为 this 和 super 指代的都是需要被创建出来的对象,而静态方法在类加载的时候就已经创建了,所以没办法在静态方法中使用 this 或 super。


11.静态方法的使用需要注意哪些问题?


静态方法的使用需要注意以下两个问题:


  • 静态方法中不能使用实例成员变量和实例方法;

  • 静态方法中不能使用 this 和 super。


12.final 修饰符的作用有哪些?


final 也是很多面试喜欢问的地方,但我觉得这个问题很无聊,通常能回答下以下 5 点就不错了:


  • 被 final 修饰的类不可以被继承

  • 被 final 修饰的方法不可以被重写

  • 被 final 修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.

  • 被 final 修饰的方法,JVM 会尝试将其内联,以提高运行效率

  • 被 final 修饰的常量,在编译阶段会存入常量池中.


除此之外,编译器对 final 域要遵守的两个重排序规则更好:


在构造函数内对一个 final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序 初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序.


经典使用场景:Integer,String 等类中有使用到。


13.覆盖 equals() 方法的时候需要遵守哪些规则?


Oracle 官方的文档对于 equals() 重写制定的规则如下。


  • 自反性:对于任意非空的引用值 x,x.equals(x) 返回值为真。

  • 对称性:对于任意非空的引用值 x 和 y,x.equals(y) 必须和 y.equals(x) 返回相同的结果。

  • 传递性:对于任意的非空引用值 x、y 和 z,如果 x.equals(y) 返回值为真,y.equals(z) 返回值也为真,那么 x.equals(z) 也必须返回值为真。

  • 一致性:对于任意非空的引用值 x 和 y,无论调用 x.equals(y) 多少次,都要返回相同的结果。在比较的过程中,对象中的数据不能被修改。

  • 对于任意的非空引用值 x,x.equals(null) 必须返回假。


此题目不要求记忆,能知道大概即可,属于加分项题目。


14.在 Object 中 notify() 和 notifyAll() 方法有什么区别?


notify() 方法随机唤醒一个等待的线程,而 notifyAll() 方法将唤醒所有在等待的线程。


如何使用 clone() 方法?


如果是同一个类中使用的话,只需要实现 Cloneable 接口,定义或者处理 CloneNotSupportedException 异常即可,请参考以下代码:


public class CloneTest implements Cloneable {    int num;    public static void main(String[] args) throws CloneNotSupportedException {        CloneTest ct = new CloneTest();        ct.num = 666;        System.out.println(ct.num);        CloneTest ct2 = (CloneTest) ct.clone();        System.out.println(ct2.num);    }}
复制代码


如果非内部类调用 clone() 的话,需要重写 clone() 方法,请参考以下代码:


class CloneTest implements Cloneable {    int num;    public static void main(String[] args) throws CloneNotSupportedException {        CloneTest ct = new CloneTest();        ct.num = 666;        System.out.println(ct.num);        CloneTest ct2 = (CloneTest) ct.clone();        System.out.println(ct2.num);    }    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();    }}public class CloneTest2 {    public static void main(String[] args) throws CloneNotSupportedException {        CloneTest ct = new CloneTest();        ct.num = 666;        System.out.println(ct.num);        CloneTest ct2 = (CloneTest) ct.clone();        System.out.println(ct2.num);    }}
复制代码


对象克隆是原型模式的经典实现。


15.java 中对象的创建方式有哪几种?


java 中提供了以下四种创建对象的方式:


  • new 创建新对象

  • 通过反射机制

  • 采用 clone 机制

  • 通过序列化机制


发布于: 2021 年 01 月 29 日阅读数: 13
用户头像

田维常

关注

关注公众号:Java后端技术全栈,领500G资料 2020.10.24 加入

关注公众号:Java后端技术全栈,领500G资料

评论

发布
暂无评论
15道类和对象面试题,快看看自己会几道