第六题,什么是封装?
封装将类的某些信息隐藏在类的内部,不允许外部程序直接访问,只能通过该类提供的方法来实现对隐藏信息的操作和访问。
例如,一台计算机内部极其复杂,有主板、CPU、硬盘和内存, 而一般用户不需要了解它的内部细节,不需要知道主板的型号、CPU 主频、硬盘和内存的大小,于是计算机制造商用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,这样做了以后,用户使用计算机就非常方便了。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
实现封装的具体步骤如下:
修改成员变量的可见性来限制对属性的访问,一般设为 private。
为每个成员变量创建一对赋值(setter)方法和取值(getter)方法,一般设为 public,用于属性的读写。
在赋值和取值方法中,加入成员变量控制语句(对成员变量值的合法性进行判断)。
public class Student { private int id; private String name; public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public int getId() { return this.id; } public String getName() { return this.name; } public static void main(String args[]) { Student student = new Student(); student.setId(1034); student.setName("沉默王二"); System.out.println("学生 id " + student.getId()); System.out.println("学生姓名 " + student.getName()); } }
第七题,抽象和封装有什么区别?
抽象只关注对象的相关数据,并隐藏所有可能无关行为的细节。它隐藏了背景细节,但强调了要点,以减少复杂性并提高效率。抽象关注的是思想而非事件。
封装将成员变量和方法绑定到单个类中,同时限制了对某些成员变量的访问。封装意味着隐藏成员变量以保护成员变量免受外部访问,从而使应用程序某一部分的更改不会影响其他部分。
抽象和封装在“定义”上的差异 —— 抽象通过隐藏不相关的细节来强调对象的所有基本方面,以提高效率并消除复杂性。封装是一种数据隐藏机制,它将数据包装在一个胶囊中以限制来自外界的访问。
抽象和封装在“功能”上的差异 —— 抽象仅强调使复杂程序更简单的基本功能,而封装则是将成员变量和操作成员变量的方法绑定到单个类中。
抽象和封装在“实现”上的区别 —— 抽象由抽象类和接口实现,而封装则通过访问权限修饰符来实现。
第八题,什么是继承?
继承是面向对象编程中非常强大的一种机制,在 Java 中使用 extends 关键字来表示继承关系。当创建一个类时,总是在继承,如果没有明确指出要继承的类,总是隐式地从根类 Object 进行继承。
class Person { public Person() { } } class Man extends Person { public Man() { } }
Person 类隐式地继承了 Object 类,因此 Person 类也自动地拥有了 hashCode()、equals()、toString() 等方法。
Man 类继承了 Person 类,这样一来,Person 类就称为父类,Man类就称为子类。如果两个类存在继承关系,子类会自动继承父类的方法和成员变量,在子类中可以调用父类的方法和成员变量。
Java 只允许单继承,也就是说一个类最多只能显式地继承一个父类。但一个类却可以被多个类继承,也就是说一个类可以拥有多个子类。
第九题,什么是多态?
多态是同一个行为具有多个不同表现形式的能力,可以使程序具有良好的扩展性,并可以对所有类的对象进行通用处理。
在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为方法重写(Override)。
public class Shape { public void getArea() { System.out.println("形状"); } } public class Rectangle extends Shape { @Override public void getArea() { System.out.println("矩形"); } public static void main(String args[]) { Shape shape = new Rectangle(); shape.getArea(); } }
方法重写和方法重载(Overload)不同,如果一个类有多个名字相同但参数个数不同的方法,我们通常称这些方法为方法重载。
public class Calculator { public int subtract(int a, int b) { return a - b; } public double subtract(double a, double b) { return a - b; } public static void main(String args[]) { Calculator calculator = new Calculator(); System.out.println("150 和 12 相差 " + calculator.subtract(150, 12)); System.out.println("15.5 和 15.4 相差 " + calculator.subtract(15.50, 15.40)); } }
通过下面这幅图可以了解到,子类 Circle、Triangle、Square 继承了父类 Shape,并且重写了 draw() 方法用于绘制不同的形状。
方法重写用于提供父类已经声明的方法的特殊实现,是实现多态的基础条件。
第十题,怎么区分关联、聚合、组合?
能体现关联(Association)关系的例子有客户和订单之间的关系、公司和员工之间的关系、用户与电脑之间的关系。关联关系所涉及的两个类是处在同一层次上的。
class Computer { public void develop() { } } class Person { private Computer computer; public Person(Computer computer) { this.computer = computer; } public void work() { computer.develop(); } }
聚合(Aggregation)是整体和个体之间的关系。聚合关系所涉及的两个类是处在不平等层次上的,一个代表整体,另一个代表部分,体现的是 has-a 的关系,比如班级和学生,班级如果不存在了学生还可以存在。
再比如说任何地址之间的关系。
public class Person { private Address address; } class Address { private String city; private String state; private String country; }
组合(Composition)关系是比聚合关系更强的关系,体现的是 is-a 的关系,比如说房子与房间,房子如果不存在了房间就没有存在的必要了。
再比如说车与轮胎、车门、车窗之间的关系。
public class Car { private Tire[] tires; private Door[] doors; private Window[] windows; } class Tire { } class Door { } class Steering { } class Window { }
好了,关于面向对象编程方面的面试题就先了解到这吧,如果能够对你在年后的面试中助一臂之力那就太好了,如果不能,温故一下封装、继承、多态方面的知识也是很有必要的。
PS:好朋友 Guide 哥的面试突击第四版可以下载了,GitHub 标星 95.3k,真的非常牛逼。第四版增加/修改的内容如下图所示。
如果你不知道获取方式的话,我提供给你一个:
链接:https://pan.baidu.com/s/19voBuI_zR4_E9qrk0iAUYA 密码:413c