面试题
面向过程和面向对象的区别
面向过程和面向对象的主要区别在于思想方式和实现方法。
面向过程重视步骤和函数,通过分解问题并设计函数来解决问题;
面向对象则更注重对象和类之间的关系,将程序中的各种元素组织成一个有机整体,在实现上更加灵活和可扩展。
同时,面向对象的程序具有更高的复用性、可维护性和可读性。
类和对象的关系
类:定义了对象应具有的特征和⾏为,类是对象的模板。
对象:拥有多个特征和⾏为的实体,对象是类的实例。
区别
- 抽象程度不同
类是一种抽象的数据结构,它描述了一组对象的共同特征,包括属性和方法等。而对象则是类的具体化,它包含了类定义的属性值和方法实现,是具体的实体。
- 内容不同
类包含了属性和方法的定义,但没有具体的值或实现。而对象则是具有这些属性值和方法实现的实体,是一个具体的实例。
- 使用方式不同
类是一种模板或者蓝图,它用于创建对象、描述对象的属性和行为等,是对实现进行了封装和抽象的结果。而对象则是类的具体实现,通过对象可以直接访问类中定义的属性和方法。
- 存储位置不同
类通常在代码中被定义,是静态的,存储于磁盘上;而对象则是在程序运行时创建的,存储于内存中。
- 可变性不同
类是一种不可变的数据结构,它定义了一组属性和方法,但不能直接改变这些属性和方法的定义。而对象则是可变的,可以修改它们的属性值或实现方法。
综上所述,类是一种描述共同特征的抽象数据类型,而对象是类的一个具体实例,包含了类定义的属性值和方法实现。类和对象之间的关系是类定义了对象的共同特征,而对象实现了这些特征。两者的使用方式、存储位置、可变性等方面也有所不同。
构造方法的作用和特征
构造方法是一种可以创建和初始化对象的特殊方法,用于在对象创建时自动调用。
构造方法与类同名,没有返回值类型,而且可以有多个重载形式。
构造方法的主要作用如下:
创建对象:构造方法在对象实例化的过程中被自动调用,用于为对象分配内存空间并初始化其状态。没有构造方法,就无法创建对象。
初始化对象:构造方法可以对对象属性进行初始化,为对象赋予初始的状态。这些属性可以是类的成员变量或者方法内部定义的局部变量。
重载构造方法:通过定义不同参数的构造方法,可以实现不同的对象初始化方式,满足不同的需求。
隐藏默认构造方法:如果没有显式定义构造方法,编译器会自动生成一个默认的构造方法。但是,这个默认构造方法并不一定符合要求,会导致代码的不可预期性和安全性问题。因此,通过定义显式构造方法可以隐藏默认构造方法。
构造方法的特征如下:
构造方法与类名相同,且没有返回值类型,包括void。
构造方法可以有多个重载形式,通过传入不同的参数来初始化对象。
如果没有显示定义构造方法,则编译器会生成一个默认的构造方法。
如果显式定义了构造方法,则需要手动调用其他构造方法。这就是构造方法的重载。
构造方法只能在对象创建时被调用,不能像一般方法那样被复用。
总之,构造方法是一种特殊的方法,其作用是创建和初始化Java对象。通过定义不同参数的构造方法可以实现不同的对象初始化方式,在Java编程中非常重要。
private、默认、protected、public四个权限修饰符的作用
在Java中,访问修饰符(access modifiers)是指用来控制类、变量和方法的可见性和访问权限的关键字。Java中有四个访问修饰符private、默认、protected和public,分别表示不同的访问级别和访问权限。
private:私有访问修饰符,用于限制只有本类中才能访问该成员(属性或方法),其他类无法访问。一般用于保护对象的属性,可以提高程序的安全性和封装性。
默认:默认访问修饰符,也称为包访问修饰符(package-level access modifier)。在没有显式定义访问修饰符时,该成员默认为默认访问权限,只有在同一包中的类才能访问该成员。
protected:受保护访问修饰符,用于限制只有本类、子类和同一包中的其他类才能访问该成员。一般用于实现继承和类方法的封装。
public:公共访问修饰符,用于标识该成员可以被任意类所访问。在许多情况下,将方法和变量声明为public不是很安全,因为这会导致类中的所有细节暴露给外部。
总之,访问修饰符是Java中控制类、变量和方法可见性和访问权限的关键字。private、默认、protected、public四个访问修饰符可以在Java程序中用来限定成员的访问级别和访问权限。在设计类时,要根据具体情况选择合适的访问修饰符,不仅能保证数据封装和安全性,还能提高程序的可读性和可维护性。
注意 :
访问权限修饰符都是成员修饰符,只能修饰成员不能修饰局部
default是默认的,没有显示的通过其他访问权限修饰符进行修饰,默认通过default修饰
能够用来修饰类的访问权限修饰符 : public | default
访问被protected修饰的成员
- 同包类下访问
- 不同包下的子类中,通过继承关系访问
方法重载和方法重写的区别
实现重载条件 :
- 一个类中的多个方法
- 方法名相同
- 参数列表不同|方法签名不同 (参数类型、参数个数、参数顺序)
方法重载的目的是为了提供更加灵活的方法调用方式。在调用方法时,编译器会根据参数类型和数量自动选择最合适的方法。方法重载的返回值类型可以相同也可以不同,但是不能仅仅是返回类型不同。
实现重写的条件 :
- 两个类中的两个方法
- 继承|实现关系
- 方法签名相同
方法重写的目的是为了改变父类方法的实现细节,增强程序的可读性和可维护性。当程序调用子类中被重写的方法时,实际上执行的是重写后的子类方法。
使用重写前提需求:当子类对从父类中所继承的功能满意,但是功能的实现不满意的时候,在子类中重写实现这个功能->重写
在Java中,方法重载(overloading)和方法重写(overriding)是两种常用的面向对象编程概念,它们具有不同的特点和作用。
方法重载:是指在同一个类中定义多个方法,它们具有相同的方法名,但是参数列表不同(参数类型、参数个数、参数顺序)。方法重载的目的是为了提供更加灵活的方法调用方式。在调用方法时,编译器会根据参数类型和数量自动选择最合适的方法。方法重载的返回值类型可以相同也可以不同,但是不能仅仅是返回类型不同。
方法重写:是指子类继承父类后,重新定义该父类中的某个方法,使得子类拥有与父类相同的名称、参数列表和返回类型的方法。方法重写的目的是为了改变父类方法的实现细节,增强程序的可读性和可维护性。当程序调用子类中被重写的方法时,实际上执行的是重写后的子类方法。
区别:
方法重载是指同一个类中,方法名相同,但是参数列表不同,返回值类型可以相同也可以不同。而方法重写是指子类重新定义父类中的方法,方法名、参数列表和返回值类型必须与父类完全一致。
方法重载是编译时多态,即在编译期确定该调用哪个方法;而方法重写是运行时多态,即在程序运行期间才能确定调用哪个方法。
方法重载主要用于提供不同的方法调用方式,增加代码的灵活性。方法重写主要用于改变父类方法的实现细节,扩展程序的功能。
总之,方法重载和方法重写都是Java中常用的面向对象编程概念,它们分别用于提供不同的方法调用方式和改变父类方法的实现细节。掌握它们的特点和使用场景,可以让你的Java程序更加灵活和可维护。
java.lang.Object类的六个常用方法的声明并说明其作用。
- public boolean equals(Object obj)
这个方法用于比较两个对象是否相等。默认情况下,equals()方法将比较两个对象的引用地址是否相等,即是否为同一个对象。如果需要比较对象的值是否相等,则需要在子类中覆写equals()方法。在覆写时需要注意,需要满足自反性、对称性、传递性和一致性等特点。- public int hashCode()
这个方法返回当前对象的哈希码,哈希码是根据对象的内部信息生成的一个整数,可以用于快速查找对象,比如在集合类中使用。hashCode()方法的默认实现会返回对象的内存地址,但是可以在子类中重新定义。- public String toString()
这个方法返回表示该对象的字符串,通常建议程序员重载这个方法,以便打印对象的属性或其他有用信息。- public final native Class<?> getClass()
这个方法返回对象所属的类Class对象。由于Object是所有类的父类,因此在Java中每个对象都可以调用getClass()方法。这个方法是用本地代码实现的。- public final void notify()
- public final void notifyAll()
这两个方法是用于线程间通信的方法,用于激活处于等待状态下的线程。notify()方法随机唤醒一个处于等待状态的线程,而notifyAll()方法唤醒所有处于等待状态的线程,让它们重新竞争执行权。
继承条件下子类构造方法的执行过程
1、在执行子类构造方法之前,会隐式地调用父类的无参构造方法,以保证父类的实例变量可以被正确初始化。如果父类没有无参构造方法,并且在子类中没有显式调用父类的其他构造方法,则编译器会报错。
2、执行子类构造方法,子类构造方法可以调用子类自身的其他构造方法或者父类的有参构造方法。
3、如果子类构造方法调用了子类自身的其他构造方法,则该构造方法必须是子类中定义的其它构造方法的第一个语句,否则编译器会报错。4、如果子类构造方法显式地调用了父类的有参构造方法,则需要使用关键字super显式调用,同时指定父类构造方法所需要的参数。调用父类构造方法的语句也必须是子类构造方法中的第一条语句。如果子类构造方法中没有显式调用父类的构造方法,则编译器会隐式地调用父类的无参构造方法。
4、子类构造方法执行完毕后,将返回一个新创建的子类对象。
super关键字的作用和使用
调用父类的构造方法:在子类构造方法中,可以使用super关键字来调用父类构造方法,以保证父类的实例变量能够被正确初始化。使用super关键字调用父类构造方法的语法super(参数列表)。
访问父类的成员变量:在子类中,可以使用super关键字来引用父类中的成员变量。这样可以避免子类和父类拥有同名变量时的命名冲突问题。使用super关键字访问父类成员变量的语法为super.父类成员变量名。
调用父类的方法:在子类中,可以使用super关键字来调用父类中的方法。这样可以避免子类和父类拥有同名方法时的命名冲突问题。使用super关键字调用父类方法的语法为super.父类方法名(参数列表)。
super关键字必须出现在子类方法或构造方法的第一条语句上。
==和equals()的联系和区别
比较的是两个对象的引用地址是否相等,也就是判断两个对象是否为同一个实例。如果两个对象的引用地址相等,则返回true,否则返回false。
equals()比较的是两个对象的内容是否相等。如果两个对象的属性值相等,则equals()返回true,否则返回false。
多态的含义和作用
多态的含义是指同一种类型的对象,在不同的情况下会表现出不同的形态和行为特征。具体来说,就是尽可能的通过抽象类型、接口或基类定义统一的数据类型,使得不同的子类可以通过继承、实现共享并重用基类的代码,并且在运行时根据实际情况动态选择相应的子类、实现或对象,以达到灵活、可扩展和高效的编程目的。
多态的作用在于:
- 简化程序的设计和维护:通过基类或接口的抽象定义,将对象从具体实现解耦,易于扩展和修改;
- 提高代码的复用和可读性:多个子类可以共享和重用父类的方法和属性,避免了重复代码的产生,同时也更方便于其他开发者理解和使用代码;
- 实现程序的松耦合和高内聚:不同的对象之间通过统一的接口和基类保持松耦合的联系,同时具备自己独立的内部实现,即高内聚性;
- 支持动态绑定和运行时多态:程序可以根据实际情况动态地选择和调用对象的方法和属性,提高了程序的灵活性和可扩展性。
向上转型和向下转型
向上转型:将子类对象转换为父类类型,这样就可以使用父类变量来代替子类变量。向上转型是自动的,也就是说不需要强制类型转换,因为子类继承父类,子类对象可以直接赋值给父类变量。
较两个对象是否相等。默认情况下,equals()方法将比较两个对象的引用地址是否相等,即是否为同一个对象。如果需要比较对象的值是否相等,则需要在子类中覆写equals()方法。在覆写时需要注意,需要满足自反性、对称性、传递性和一致性等特点。
- public int hashCode()
这个方法返回当前对象的哈希码,哈希码是根据对象的内部信息生成的一个整数,可以用于快速查找对象,比如在集合类中使用。hashCode()方法的默认实现会返回对象的内存地址,但是可以在子类中重新定义。- public String toString()
这个方法返回表示该对象的字符串,通常建议程序员重载这个方法,以便打印对象的属性或其他有用信息。- public final native Class<?> getClass()
这个方法返回对象所属的类Class对象。由于Object是所有类的父类,因此在Java中每个对象都可以调用getClass()方法。这个方法是用本地代码实现的。- public final void notify()
- public final void notifyAll()
这两个方法是用于线程间通信的方法,用于激活处于等待状态下的线程。notify()方法随机唤醒一个处于等待状态的线程,而notifyAll()方法唤醒所有处于等待状态的线程,让它们重新竞争执行权。
继承条件下子类构造方法的执行过程
1、在执行子类构造方法之前,会隐式地调用父类的无参构造方法,以保证父类的实例变量可以被正确初始化。如果父类没有无参构造方法,并且在子类中没有显式调用父类的其他构造方法,则编译器会报错。
2、执行子类构造方法,子类构造方法可以调用子类自身的其他构造方法或者父类的有参构造方法。
3、如果子类构造方法调用了子类自身的其他构造方法,则该构造方法必须是子类中定义的其它构造方法的第一个语句,否则编译器会报错。4、如果子类构造方法显式地调用了父类的有参构造方法,则需要使用关键字super显式调用,同时指定父类构造方法所需要的参数。调用父类构造方法的语句也必须是子类构造方法中的第一条语句。如果子类构造方法中没有显式调用父类的构造方法,则编译器会隐式地调用父类的无参构造方法。
4、子类构造方法执行完毕后,将返回一个新创建的子类对象。
super关键字的作用和使用
调用父类的构造方法:在子类构造方法中,可以使用super关键字来调用父类构造方法,以保证父类的实例变量能够被正确初始化。使用super关键字调用父类构造方法的语法super(参数列表)。
访问父类的成员变量:在子类中,可以使用super关键字来引用父类中的成员变量。这样可以避免子类和父类拥有同名变量时的命名冲突问题。使用super关键字访问父类成员变量的语法为super.父类成员变量名。
调用父类的方法:在子类中,可以使用super关键字来调用父类中的方法。这样可以避免子类和父类拥有同名方法时的命名冲突问题。使用super关键字调用父类方法的语法为super.父类方法名(参数列表)。
super关键字必须出现在子类方法或构造方法的第一条语句上。
==和equals()的联系和区别
比较的是两个对象的引用地址是否相等,也就是判断两个对象是否为同一个实例。如果两个对象的引用地址相等,则返回true,否则返回false。
equals()比较的是两个对象的内容是否相等。如果两个对象的属性值相等,则equals()返回true,否则返回false。
多态的含义和作用
多态的含义是指同一种类型的对象,在不同的情况下会表现出不同的形态和行为特征。具体来说,就是尽可能的通过抽象类型、接口或基类定义统一的数据类型,使得不同的子类可以通过继承、实现共享并重用基类的代码,并且在运行时根据实际情况动态选择相应的子类、实现或对象,以达到灵活、可扩展和高效的编程目的。
多态的作用在于:
- 简化程序的设计和维护:通过基类或接口的抽象定义,将对象从具体实现解耦,易于扩展和修改;
- 提高代码的复用和可读性:多个子类可以共享和重用父类的方法和属性,避免了重复代码的产生,同时也更方便于其他开发者理解和使用代码;
- 实现程序的松耦合和高内聚:不同的对象之间通过统一的接口和基类保持松耦合的联系,同时具备自己独立的内部实现,即高内聚性;
- 支持动态绑定和运行时多态:程序可以根据实际情况动态地选择和调用对象的方法和属性,提高了程序的灵活性和可扩展性。
向上转型和向下转型
标签:面试题,调用,Java,构造方法,对象,子类,父类,方法 From: https://www.cnblogs.com/Heyking/p/17316257.html 向上转型:将子类对象转换为父类类型,这样就可以使用父类变量来代替子类变量。向上转型是自动的,也就是说不需要强制类型转换,因为子类继承父类,子类对象可以直接赋值给父类变量。
向下转型:将父类对象转换为子类类型,这需要使用强制类型转换,并且只有当父类对象本身就是对应的子类对象时才能成功转换。