目录
一、面向对象与面向过程的区别
二、创建一个对象用什么运算符,对象实体与对象引用有什么区别?
三、对象的相等和引用的相等有什么区别
四、如果一个类没有构造方法,程序能正常执行吗?
五、构造方法有什么特点,可以被重写吗?
六、面向对象的三大特征
七、接口和抽象类的异同
面向过程是以方法为单位,都是直接的一个一个的方法调用
面向对象则是将万事万物都抽象成对象,然后调用对象里面的方法,来操作对象里面的数据。就是封装了一层相对于面向过程
面向对象更加的 易复用、易维护、易扩展
但是面向过程效率更好
new
对象实体是直接存在于堆中,而对象引用不一定在堆中 如果是非static 非final的成员属性那么就存在与堆中 如果是static的final的就存在于方法区 如果是方法里面的就是存在于虚拟机栈的局部变量表中
对象的相等是说对象的内容一样
对象的引用相等指的是对象的引用地址相等
可以正常执行,因为系统会提供一个默认的无参构造方法
特点:
1. 样子:
和类同名,而且没有返回值 连void都没有
2. 执行的时间
是创建对象的时候自动执行,无需手动调用
不能被重写
重写没有意义 构造方法肯定只能是在本类中用来创建本类的对象的
封装性
将数据隐藏在对象的内部,不能直接进行访问 可以通过对外的方法进行访问
它是使用权限修饰符实现的
不仅可以封装属性 还可以封装方法、构造器等 例如单例模式就是对构造器进行封装 使用private修饰 不能直接创建对象
封装性描述的是可见性的大小 是否能被看到
继承性
它是使用已存在的类来创建新的类的一种方法
就可以在子类中无需再次编写父类中的那些属性方法,就能获取到父类中的属性方法
大大提高了代码复用性、扩展性(无需编写,容易扩展)
注意:这里其实是能够获取到父类中所有的属性和方法,包括私有的
只是说私有的不能直接访问,而可以使用公共方法来进行访问
多态性
多态顾名思义就是多种形态,就是子类实例的多种形态
父类引用指向子类对象,这个子类对象可以是多变的 只要构成了父子关系或者是接口的实现关系
作用就是大大的提高了程序的灵活性,左边的父类引用可以不变,而右边的子类对象可以发生改变
其实面向接口、面向抽象编程就是基于多态性实现的 已到达高内聚低耦合的效果
例如在jdbc编程这个典型的面向接口编程,就是只需要设定一套接口规则 由不同的数据库厂商按照自己的情况来编写其具体的实现类即可
相同点:
1. 都不能被实例化
2. 都可以在其中定义抽象方法,由具体的子类/实现类去根据需要具体实现
3. 都可以定义默认方法 静态方法(接口JDK8中)
不同点:
1. 接口描述的一种规范,一种功能 如果实现了一个接口 表示的是具备了一种功能 而没有其他关系了 而抽象类 继承了抽象类则是一种is a 的关系 父子关系 更多的是一种代码的复用
接口的典型应用就是面向接口编程,还有动态代理(GDK动态代理)等....
抽象类的典型应用:模板方法设计模式 可以在抽象类中定义好一套模板 只是保留部分的抽象方法,交由子类去具体实现
2. 接口可以多继承 而抽象类只能单继承
3. 接口中的属性必须是 public static final的 而且还必须赋上初值
而抽象类中属性默认是default的 可以不去赋上初值,有默认值 可以被子类重新定义 重新赋值
4. 接口没有构造器 而抽象类中有构造器 即使不能实例化但也是有构造器的,这个构造器用于子类实例话的时候 需要调用父类的构造器 以达到能够获取到父类中的结构
八、深拷贝和浅拷贝了解吗?
浅拷贝是说也是拷贝了,但是仅仅只是基本数据类型的拷贝 而对于引用类型 只是复制了其引用 所以其对象实体并没有复制 还是使用的同一个对象实体
具体实现可以让类实现Cloneable接口,实现clone方法 然后在这个方法中调用Object类中的clone方法然后返回即可:
public class Address implements Cloneable{
private String name;
// 省略构造函数、Getter&Setter方法
@Override
public Address clone() {
try {
return (Address) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
可以发现其对象引用只是复制,实体没有复制:
public class Person implements Cloneable {
private Address address;
// 省略构造函数、Getter&Setter方法
@Override
public Person clone() {
try {
Person person = (Person) super.clone();
return person;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
结果:
Person person1 = new Person(new Address("武汉"));
Person person1Copy = person1.clone();
// true
System.out.println(person1.getAddress() == person1Copy.getAddress());
深拷贝就是完完全全的拷贝,其引用类型的属性,不是简单的复制其对象引用,而是一个全新的对象然后再赋值给属性
可以通过再次设值的方法实现深拷贝:
@Override
public Person clone() {
try {
Person person = (Person) super.clone();
person.setAddress(person.getAddress().clone());
return person;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
此时的结果就是false了
当然深拷贝简单一点的话,可以使用序列化和反序列化的方式