1. 描述方法重载和重写的区别
方法重载是发生在同一个类中,方法重写发生在子父类之间。
-
类中有多个方法,具有相同的方法名,但是方法的参数各不相同,这种情况被称为方法的重载。(overload)
(1)方法的名字必须相同;
(2)方法的参数列表必须不同:
参数的类型不同;
参数的个数不同;
参数的顺序不同;
(3)方法的修饰符、返回类型、抛出异常这些地方没有限制(可以相同,也可以不同,但一般都是相同的) -
如果子类和父类中出现了相同的方法,这种情况就叫做方法重写。(override)
(1)方法名必须相同;
(2)参数列表必须相同;
(3)访问控制修饰符可以被扩大,但是不能被缩小:public > protected > default > private
(4)方法抛出异常类型的范围可以被缩小,但是不能被扩大:Exception>ClassNotFoundException
(5)返回类型可以相同,也可以不同:
如果父类的返回类型是引用类型,子类重写后的方法返回类型可以和父类方法的返回类型保持一致,也可以是父类方法返回类型的子类型;
如果父类的返回类型是基本类型,那么子类重写后的返回类型必须和父类的保持一致。
子类继承父类,在调用方法的时候,如果子类中没有重写,那么调用的是从父类继承的方法;如果子类重写了这个方法,那么将会调用到子类中重写后的方法。
2. 一个类中,是否总会存放默认的无参构造器?
如果在类中没有定义构造器,那么在编译之后,也会自动的生成一个无参构造器,并且构造器中不执行任何代码。这个无参构造器就被称为默认的构造器。如果我们在类中定义了一个构造器,那么系统就不再为该类生成无参的默认构造器了。
3. 下面的代码能否通过编译?
public class A{
protected int test(){
return 0;
}
}
class B extends A{
public long test(){
return 0L;
}
}
一个类中不允许出现没有任何关系的同名关系。子类B和父类A明显是重写关系,父类的返回类型是基本数据类型,所以子类的类型必须和父类相同。
4. static成员变量和非静态成员变量的区别
-
static静态成员变量:
(1)静态属性是属于类的,可以直接使用类名来访问,也可以使用对象访问,但推荐使用类名访问。
(2)类中的静态属性,跟随着类,一起保存在内存中的方法区。
(3)类加载到内存中(方法区)的时候,系统就会给类中的静态属性做初始化赋默认值,就算还没有创建对象,只要这个类加载到了内存,就可以直接使用类名来访问静态属性,因为这个时候静态属性已经完成了初始化赋默认值的操作。 -
非静态成员变量:
(1)非静态属性,是属于对象的,一定要使用对象来访问。
(2)当创建对象的时候,对象中只会保存类中定义的非静态属性的信息,而静态属性是不会进入到对象中的。
(3)非静态属性创建对象后,系统会自动给对象中的非静态属性做初始化赋默认值,也正是因为这个原因,非静态属性只有在创建对象后,使用对象才能访问。
在Java类中,可以用static修饰属性、方法、代码块、内部类。static修饰的方法不能被重写。
5. abstract的作用
abstract修饰符,可以修饰类、方法:
(1)如果abstract修饰方法,那么该方法就是抽象方法。抽象方法的特点就是只有方法的声明,没有方法的实现。
(2)如果abstract修饰类,那么该类就是抽象类。抽象类中可以写抽象方法,不能进行实例化创建对象。抽象类中可以没有抽象方法,但抽象方法所在的类一定要声明为抽象类。抽象类就是用来被继承的。抽象类中也有构造器,子类创建对象时要先调用父类的构造器。
6. final关键字的作用
final修饰符,可以用来修饰类、变量、方法:
- 用final修饰的类不能被继承,也就是说这个类是没有子类的。
- 用final修饰的方法可以被子类继承,但是不能被子类的重写。
- 用final修饰的变量就变成了常量,并且它只能被赋一次值,第二次赋值就会报错。
(1)final修饰非静态成员变量:JVM不会为其默认赋值,我们需要手动在声明的同时、匿名代码块中、构造器中赋值,并且类中出现的所有构造器都要赋值。
(2)final修饰静态成员变量:JVM不会为其默认赋值,需要手动在声明的同时、静态代码块中赋值。
(3)final修饰引用类型变量:此时的final指的是,引用s的指向的对象不能改变,但是可以使用s来操作当前指向的对象属性和方法。
7. 单例(Singleton)设计模式
- 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。
- 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
- 首先必须将类的构造器的访问权限设置为private,这样在类的外部就不能new创建对象了,只能在类的内部创建对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以指向类内部产生的该类对象的变量也必须定义成静态的。
饿汉式单例:
class Singleton {
// 1.私有化构造器
private Singleton() {}
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single = new Singleton();
// 3.提供公共的静态的方法,返回当前类的对象
public static Singleton getInstance() {
return single;
}
}
懒汉式单例:
class Singleton {
// 1.私有化构造器
private Singleton() {}
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single;
// 3.提供公共的静态的方法,返回当前类的对象
public static Singleton getInstance() {
if(single == null) {
single = new Singleton();
}
return single;
}
}
- 单例模式的优点:由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
8. this和super的作用
-
this:区别成员变量和局部变量;调用类中的其他方法;调用类中的其他构造器。
this关键字的含义:this表示所在类的当前对象的引用(地址值),即对象自己的引用。 -
super:在子类中,可以访问父类中的属性;调用父类中的方法;调用父类中的构造器。