2023 年 30 个 OOP 面试问题和答案
面向目标编程(OOPs)是一种在程序中完成**目标概念的编程范式。它旨在通过在编程中完成承继、笼统、多态等实践国际中的实体,为实践国际中的问题提供更简便的解决方案。OOPs概念被广泛运用于Java、Python、C++等多种盛行言语中。
OOPs也是编程面试中最重要的论题之一。本文包括了关于OOPs概念的一些顶级面试问题。
OOP 面试问题
1. 什么是面向目标编程(OOP)?
面向目标编程(也称为OOPs)是一种编程范式,其中完好的软件作为一组相互沟通的目标运转。一个目标是一组数据和操作这些数据的办法。
2. 为什么运用OOPs?
OOP的首要优势是更易于办理的代码,具有以下特色:
- 增加了对软件全体了解,使开发人员与用户之间的言语距离缩小。
- 面向目标通过封装简化了保护工作。能够通过保持办法不变轻松地改动底层表明。
- OOP范式首要适用于相对较大规划的软件。
3. 什么是类?
类 是面向目标程序中的构建块。它是一个用户界说的数据类型,包括操作数据成员和成员函数。它类似于具有共同特点和办法的目标蓝图或模板。
4. 什么是目标?
目标 是类的实例。不能直接运用类的数据成员和办法。咱们需求创立一个类(或实例)来运用它们。简单来说,它们就是具有状况和行为的实在国际实体。
例如:下面代码展现了怎么创立一个类(即一个目标) 的示例
- C++
- Java
- Python3
- C#
#include <iostream>
using namespace std;
class Student{
private:
string name;
string surname;
int rollNo;
public:
Student(string studentName, string studentSurname, int studentRollNo){
name = studentName;
surname = studentSurname;
rollNo = studentRollNo;
}
void getStudentDetails(){
cout << "The name of the student is " << name << " " << surname << endl;
cout << "The roll no of the student is " << rollNo << endl;
}
};
int main() {
Student student1("Vivek", "Yadav", 20);
student1.getStudentDetails();
return 0;
}
Output
The name of the student is Vivek Yadav
The roll no of the student is 20
5. 面向目标编程的首要特色是什么?
面向目标编程(OOPs)的首要特色,也被称为4个支柱或根本原则如下:
- 封装
- 数据笼统
- 多态性
- 承继
OOPs 首要功用
6. 什么是封装?
封装是将数据和操作这些数据的办法绑定到一个单元中,以便将敏感数据躲藏起来,不让用户直接拜访。它通过以下进程完成:
- 数据躲藏:
- Java
//封装的简单演示
//它有一个私有数据成员以及 getter 和 setter 办法。public class Student{
//private data members
private String name;
private int rollNo;
//拜访称号的公共获取办法
public String getName(){
return name;
}
//拜访 rollNo 的公共 getter 办法
public int getRollNo(){
return rollNo;
}
//设置称号的公共设置办法
public void setName(String name){
this.name=name
}
//设置 rollNo 的公共设置办法
public void setRollNo(int rollNo){
this.rollNo=rollNo;
}
}
7. 什么是笼统?
笼统类似于数据封装,在面向目标编程中非常重要。它意味着只展现必要的信息,并将其他不相关的信息躲藏起来,以便用户运用。笼统通过运用类和接口来完成。
- Java
//implementation of abstraction through abstract class
abstract class Animal {
abstract void walk();
void eat()
{
System.out.println("The animal is eating.");
}
Animal()
{
System.out.println(
"An Animal is going to be created.");
}
}
class Cow extends Animal {
Cow() { System.out.println("You have created a Cow"); }
void walk() { System.out.println("Cow is walking."); }
}
class Goat extends Animal {
Goat()
{
System.out.println("You have created a Goat");
}
void walk() { System.out.println("Goat is walking."); }
}
public class OOPS {
public static void main(String args[])
{
Cow cow = new Cow();
cow.walk();
cow.eat();
Goat goat = new Goat();
goat.walk();
goat.eat();
}
}
8. 什么是多态性?
“多态性”一词意味着具有许多办法。它是某些代码根据不同的上下文而表现出不同行为的特点。例如,在C++言语中,咱们能够界说具有相同称号但根据上下文而有不同工作办法的多个函数。
根据目标或函数调用在何时解析,能够将多态性分为两种类型。它们如下:
A. 编译时多态性 B. 运转时多态性
A) 编译时多态性
编译时多态性,也称为静态多态性或前期绑定,是一种在编译时将调用与其代码绑定的类型的多样化。办法重载或运算符重载都是编译时多态性的示例。
B) 运转时多态性
也称为动态多样化或晚期绑定,运转时 多样化 是一种在运转时刻 或履行进程中确认函数实践完成 的 多 样 化 。 办法掩盖 是这种办法 的 一个 示例 。
- Java
// An example of method overloading
class Student {
String name,surname;
int rollNo;
public void showStudentDetails(String name) {
System.out.println("The name of the student is " + name);
}
public void showStudentDetails(int rollNo) {
System.out.println("the roll no of the student is "+ rollNo);
}
public void showStudentDetails(String name, String surname, int rollNo) {
System.out.println(name);
System.out.println(surname);
System.out.println(age);
}
}
- Java
// 办法躲避的一个比如
class Student {
public void read() {
System.out.println("The student is reading");
}
}
class SchoolStudent extends Student {
public void read(String book) {
System.out.println("the student is reding "+ book);
}
}
class CollegeStudent extends Student {
public void read(String researchPaper , String labJournal) {
System.out.println("the student is reading "+researchPaper +" and "+ labJournal);
}
}
9. 什么是承继?它的意图是什么?
承继的概念很简单,一个类派生自另一个类,并运用那个其他类的数据和完成。被派生的类称为子类或派生类
- Java
// 承继的一个比如
class Student {
public void read() {
System.out.println("The student is reading");
}
}
class SchoolStudent extends Student {
public void read(String book) {
System.out.println("the student is reding "+ book);
}
}
10. 拜访修饰符是什么?它们在面向目标编程中的重要性是什么?
拜访修饰符是一种特别类型的关键字,用于指定或操控类、办法等实体的可拜访性。私有(Private) 、公共(Public) 和受保护(Protected) 都是拜访修饰符或拜访限定词的示例。 面向目标编程中的关键组成部分——封装和数据躲藏,很大程度上得益于这些拜访修饰符。
- Java
class User {
public String userName;
protected String userEmail;
private String password;
public void setPassword(String password) {
this.password = password;
}
}
public class OOPS {
public static void main(String args[]) {
User user1 = new User();
user1.userName = "Vivek_Kumar_Yadav";
user1.setPassword("abcd@12345");
user1.userEmail = "abc@gmail.com";
}
}
11. 面向目标编程(OOP)的优缺点是什么?
OOP 的优势 | OOP 的缺点 |
---|---|
OOPs 提高了代码的可重用性。 | 程序员应该具有杰出的技能,并且在面向目标方面有超卓的思维,由于在面向目标编程中一切都被视为目标。 |
代码更容易保护和更新。 | 恰当的规划是必要的,由于面向目标编程有点扎手。 |
它通过约束数据拜访和防止不必要的暴露,提供更好的数据安全性。 | OOP的概念并不适用于一切类型的问题。 |
快速施行和易于重新规划,然后最大程度地削减全体程序的复杂性。 | 程序的长度与进程化办法相比要大得多。 |
12. 除了面向目标编程(OOP),还有哪些其他的编程范式存在?
编程范式是指编写程序的技能或办法。编程范式能够分为以下几种类型:
-
1. 指令式编程范式
它是一种通过赋值句子改动程序状况的编程范式。这种范式的首要关注点在于怎么完成目标。以下编程范式归于此类别:
- 进程化编程范式:该编程范式根据进程调用概念。在此典范中,进程(也称为例行程序或函数)是程序的根本构建块。
- 面向目标编程或OOP:在这个典范中,咱们将每个实体视为一个目标,并试图根据该目标的状况和行为来安排程序结构。
- 并行编程:并行编程模型通过将指令分红多个较小部分并一起履行它们来进行处理。
2. 声明性编程范式
声明性编码侧重于履行内容而不是怎么履行内容。在这种模型中,咱们表达计算逻辑而不考虑其操控流。声明性模型能够进一步分类为:
- 逻辑化编码模型:它根据办法逻辑,在其中程序句子以逻辑办法表达问题的事实和规矩。
- 函数化编码模型:在这种模型中,通过运用和组合函数来创立程序。
- 数据库化编码模型:数据库化的代码模型被用于办理以字段、记录和文件办法安排的数据和信息。
13. 结构化编程和面向目标编程之间有什么差异?
结构化程序规划(Structured Programming)是一种被视为 OOP 先驱的技能,通常由结构杰出且别离的模块组成。它是程序规划的一个子集。OOP 与结构化编程的差异如下:
面向目标编程 | 结构编程 |
---|---|
面向目标的编程建立在具有状况和行为的目标之上。 | 一个程序的逻辑结构是由结构化编程提供的,它将程序分解为相应的函数。 |
它选用自下而上的办法。 | 它遵从自上而下的办法。 |
约束数据的敞开流动,仅向授权部分提供更好的数据安全。 | 没有对数据流的约束。任何人都能够拜访数据。 |
由于多态性和承继的概念,代码的可重用性得到了增强。 | 代码的可重用性是通过运用函数和循环来完成 |
在这种情况下,办法是全局编写的,代码行逐行处理,即按顺序运转。 | 在这种情况下,该办法以动态办法工作,根据代码的需求进行调用一段时刻。 |
修正和更新代码更容易。 | 修正代码相对于面向目标编程来说是困难的。 |
数据在面向目标编程中更加重要。 | 代码被赋予更多的重要性。 |
14. 一些常用的面向目标编程言语有哪些?
OOPs范式是最盛行的编程范式之一。它广泛运用于许多盛行的编程言语,例如:C++
, java
python
javascript
c#
Ruby
15. 什么是多态的不同类型?
-
多态性能够根据调用目标或函数的解析时刻分为两种类型。它们如下:
- 编译时多态性
- 运转时多态性
多态的类型
A) 编译时多态性
编译时多态性,也称为静态多态性或前期绑定,是一种在编译时将调用与其代码绑定的多态性。办法重载或运算符重载是编译时多态性的示例。
B) 运转时多态性
也称为动态多态性或晚期绑定,运转时多态性是一种在运转时或履行进程中确认函数实践完成的类型。办法掩盖是这种办法的一个比如。
16. 重载和掩盖之间有什么差异?
名为重载的编译时多态特征允许一个实体具有相同称号但不同完成办法的众多版别。办法重载和操作符重载都是两个比如。
掩盖是一种办法的运转时多态,在其中以相同称号但不同完成办法履行一个实体。它凭借虚函数来完成。
17. 有关承继是否存在任何约束吗?
当你具有更多权威时会面对更多应战。虽然承继是一种非常强大的面向目标编程特性,但它也有明显的缺点。
- 由于必须通过几个类来完成,承继需求更长时刻进行处理。
- 基类和子类都参加承继,并且彼此之间关系密切(称为紧耦合)。因此,假如需求进行更改,则或许需求一起在两个类中进行修正。
- 施行承继或许也很困难。因此,假如没有正确施行,或许会导致意想不到的过错或不准确的输出。
18. 有哪些不同类型的承继?
承继能够分为以下5种类型:
- 单承继: 子类直接从基类派生
- 多重承继: 子类派生自多个基类。
- 多级承继: 子类派生自一个一起也派生自另一个基类的类。
- 层次承继: 多个子类派生自一个基类。
- 混合承继: 承继由上述指定的多种承继类型组成。
- Java
// 单承继的一个比如
class Father {
// 父亲的任何特定特点和功用
}
class Son extends Father {
//承继了父类的特点和函数
}
- Java
// 一个层次承继的示例
class Father {
// 任何特定于父亲的特点和函数
}
class Son extends Father {
//承继了父类的特点和函数
}
class Daughter extends Father {
//承继了父类的特点和函数
}
- Java
// 多级承继的一个比如
class Father {
// 父亲的任何特定特点和功用
}
class Son extends Father {
//承继父亲的特点和功用
}
class GrandChild extends Son {
}
19. 什么是 interface?
一种独特的类类型被称为接口,它包括办法但不包括其界说。在接口内部,只允许进行办法声明。你不能运用接口创立目标。相反,你必须将该接口投入运用,并指定履行此操作的步骤。
20. 笼统类与接口有何不同?
笼统类和接口都是特别类型的类,它们只包括办法的声明而不包括完成。尽管如此,笼统类与接口完全不同。以下是笼统类和接口之间的一些首要差异:
笼统类 | Interface |
---|---|
当一个笼统类被承继时,子类并不需求在实践运用之前提供笼统办法的界说。 | 当一个接口被完成时,子类需求指定一切接口的办法以及它们的完成。 |
一个笼统的类能够一起具有笼统办法和非笼统办法。 | 一个接口只能具有笼统办法。 |
一个笼统类能够具有final、非final、静态和非静态变量。 | 接口只有静态和终究变量。 |
笼统类不支撑多重承继。 | 一个接口支撑多重承继。 |
21.一个类占用多少内存?
类不运用内存。它们只是作为创立项意图模板而存在。现在,当目标被创立时,它们实践上会初始化类的成员和办法,并在此进程中运用内存。
22. 从类中创立目标是否总是必要的么?
不需求。 假如基类包括非静态办法,则必须结构一个目标。可是,假如类包括静态办法,则不需求生成目标。在这种情况下,您能够运用类名直接调用那些静态办法。
23. 在C++中,结构体和类之间有什么差异?
在C++中,结构体和类之间有什么差异?
- 结构体和类之间的首要差异在于,在结构体中,成员默以为公共拜访级别,而在类中,默以为私有拜访级别。
- 另一个差异是,在 C++ 中,咱们运用 struct 来声明结构,而运用 class 来声明类。
24. 什么是结构函数?
结构函数是一段代码块,用于初始化新创立的目标。结构函数类似于实例办法,但它不是一个办法,由于它没有返回类型。通常情况下,结构函数与类名相同,但在某些言语中或许会有所不同。例如:
在Python中,结构函数被命名为init。
在C++和Java中,结构函数的称号与类名相同。
Example:
- C++
class Student {
String name;
String surname;
int rollNo;
Student()
{
cout<< "contructor is called";
}
}
- java
class Student {
String name;
String surname;
int rollNo;
Student()
{
System.out.println("contructor is called");
}
}
- Python
class base:
def __init__(self):
print("This is a constructor")
25. C++中有哪些不同类型的结构函数??
C++中有哪些不同类型的结构函数?
- 默许结构函数
- 非参数化结构函数
- 参数化结构函数
- 仿制结构函数
1. 默许结构函数
默许结构函数是一个不接受任何参数的结构函数。它是一个非参数化的结构函数,在没有提供显式结构函数界说时,由编译器主动界说。
它将数据成员初始化为它们的默许值。
2. 非参数化结构函数
它是一个没有参数的用户界说结构函数。
Example:
- C++
class Student {
String name;
String surname;
int rollNo;
Student()
{
cout << "Non-parameterized contructor is called" ;
}
}
- Java
class Student {
String name;
String surname;
int rollNo;
Student()
{
System.out.println("Non-parameterized contructor is called");
}
}
- Python3
class base:
def __init__(self):
print("This is a non-parameterized constructor")
3. 参数化结构函数
The constructors that take some arguments are known as parameterized constructors.
Example:
- C++
class Student {
String name;
String surname;
int rollNo;
Student(String studentName, String studentSurname, int studentRollNo)
{
cout << "Constructor with argument is called";
}
}
- Java
class Student {
String name;
String surname;
int rollNo;
Student(String studentName, String studentSurname, int studentRollNo)
{
System.out.println("Constructor with argument is called");
}
}
- Python3
class base:
def __init__(self, a):
print("Constructor with argument: {}".format(a))
4. 仿制结构函数
一个仿制结构函数是一个成员函数,它运用同一类的另一个目标来初始化一个目标。
Example:
- C++
class Student {
String name, surname; int rollNo;
Student(Student& student) // copy constructor
{
name = student.name;
surname=student.surname;
rollNo= student.rollNo;
}
}
- Java
class Student {
String name, surname; int rollNo;
Student(Student student) // copy constructor
{
this.name = student.name;
this.surname=student.surname;
this.rollNo= student.rollNo;
}
}
在Python中,咱们没有像Java和C++那样的内置仿制结构函数,可是咱们能够运用不同的办法来完成一个解决方案。
26. 什么是析构函数?
析构函数是一种在目标超出范围或被毁掉时主动调用的办法。
在C++中,析构函数的称号与类名相同,但前缀为(~)波浪线符号。
在Python中,析构函数的称号为del。
Example:
- C++
class base {
public:
~base() { cout << "This is a destructor"; }
}
- Python3
class base:
def __del__(self):
print("This is destructor")
在Java中,废物收集器会主动删去无用的目标,因此在Java中没有析构函数的概念。咱们能够运用finalize()办法作为Java析构函数的代替办法,但自Java 9起该办法也已被弃用。
27. 咱们能够在一个类中重载结构函数吗?
咱们能够在类中重载结构函数。事实上,默许结构函数、带参数的结构函数和复制结构函数都是结构函数的重载办法。
28. 咱们能够在一个类中重载析构函数吗?
不。在一个类中不能重载析构函数。一个类中只能有一个析构函数存在。
29. 什么是虚函数?
虚函数是用于在派生类中掩盖父类办法的函数。它用于提供类的笼统。
在C++中,运用virtual关键字声明虚函数。
在Java中,每个公共、非静态和非终究办法都是虚函数。
Python办法始终是虚拟的。
Example:
- C++
class base {
virtual void print()
{
cout << "This is a virtual function";
}
}
- Java
class base {
void func()
{
System.out.printIn("This is a virtual function")
}
}
- Python3
class base:
def func(self):
print("This is a virtual function")
30. 什么是纯虚函数?
一个纯虚函数,也被称为笼统函数,是一个不包括任何句子的成员函数。假如需求,这个函数会在派生类中进行界说。
Example:
- C++
class base {
virtual void pureVirFunc() = 0;
}
- Java
abstract class base {
abstract void prVirFunc();
}
在Python中,咱们运用ABC(笼统基类)模块的@abstractmethod来完成这一点。