面向对象
一、谈谈你对面向对象的理解?
面向对象,主要就是将现实中的对象抽象成一个类,这个对象具有一定的属性和行为,类是一个抽象的概念,对象就是类的实例。例如:动物是一个类,猫是一个对象。
面向对象的目的:是为了实现程序的可扩展性、可维护性和可重用性。
二、面向对象和面向过程的区别?
面向过程:面向过程性能比面向对象高。因为类调用时需要实例化,开销比较大,比较消耗资源,所以性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发。但是,面向过程没有面向对象易维护、易复用、易扩展。
面向对象:面向对象易维护、易复用、易扩展。因为面向对象有封装、继承、多态性的特性,所以可以设计出低耦合的系统,是系统更加灵活、更加易于维护。但是面向对性能比面向过程低。
三、面向对象的三大特性
三大特性:封装(可扩展性)、继承(可扩展性和可重用性)、多态(可扩展性和可维护性)。
1.1 封装
封装(可扩展性):是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。封装可以被认为是一个保护屏障,防止类的代码和数据被外部定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。适当的封装可以让程序码更容易理解与维护,也加强了程序码的安全性。
1.2 封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
1.3 实现Java封装的步骤
1.修改属性的可见性来显示对属性的访问(一般限制为private),例如:
public class Person{
private String name;
private int age;
}
这段代码中,将name和age属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
2.对每个值提供对外的公共方法访问,也就是创建一堆赋取值方法,用于对私有属性的访问,例如:
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
采用this关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
以上实例中public方法是外部访问该类成员变量的入口。通常情况下,这些方法被称为getter和setter方法。因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。
2.1 继承
继承(可扩展性和可重用性):就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
2.2 类的继承格式
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类 {
}
class 子类 extends 父类 {
}
2.3 继承有哪些类型?
需要注意的是 Java 不支持多继承,但支持多重继承。

2.4 继承有哪些特性?
- 子类拥有父类非private的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java的继承是单继承和多重继承。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
2.5 继承有哪些关键字有什么作用?
1.extends关键字
在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以extends只能继承一个类。
2.implements关键字
使用implement关键字可以变相的使Java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
3.super关键字
通过super关键字来实现父类成员的访问,用来引用当前对象的父类。
4.this关键字
指向自己的引用。
5.final关键字
final关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写。
注:实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final
2.6 什么是构造器?
子类是不能继承父类的构造器(构造方法或者构造函数)的,它只是调用父类构造器带有参数,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。如果父类构造器没有参数,则在子类的构造器中不需要super关键字调用父类构造器,系统会自动调用父类的无参构造器
2.7 构造器 Constructor 是否可被 override?
在继承的时候我们就知道父类的私有属性和构造方法不能被继承,所以Constructor也就不能被override(重写),但是可以overload(重载),所以你可以看到一个类中有多个构造函数的情况。
2.8 Java是否支持多继承?
Java中的类不支持多继承,只支持单继承(即一个类只有一个父类)。但是Java中的接口支持多继承(即一个子接口可以有多个父接口)。接口的作用是用来扩展对象的功能,一个子接口继承父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展相应的功能。
2.9 String是否能被继承?
不能,char数组用final修饰的。
3.1 多态
多态(可扩展性和可维护性):是同一行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。多态性是对象多种表现形式的体现。
3.2 多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
3.3 多态存在的三个必然条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
3.4 多态的实现方式
- 重写
- 接口
- 抽象类和抽象方法

3.5 Java中实现多态的机制是什么?
Java中的多态靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
四、抽象类
1.1 抽象类
- 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
- 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
- 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
- 父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
- 在Java语言中使用abstract class来定义抽象类。
1.2 抽象类总结规定
- 抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类也已创建对象。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
- 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
1.3 抽象类和接口的区别是什么?
- 实现:抽象类的子类使用extends来继承;接口必须使用implements来实现接口。
- 构造函数:抽象类可以有构造函数;接口不能有。
- 实现数量:类可以实现多个接口;但只能继承一个抽象类。
- 访问修饰符:接口中的方法默认使用public;抽象类中的抽象方法可以使用public和protected修饰,如果抽象方法修饰符为private,则报错。接口除了static、final变量,不能有其他变量,而抽象类则不一定。
- 设计层次:抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范。
1.4 抽象类必须要有抽象方法吗?
不需要,抽象类不一定非要有抽象方法;但是包含一个抽象方法的类一定是抽象类。
1.5 普通类和抽象类有哪些区别?
- 普通类不能包含抽象方法,抽象类可以包含抽象方法。
- 抽象类是不能被实例化的,就是不能用new调出构造方法创建对象,普通类可以直接实例化。
- 如果一个类继承于抽象类,则该子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。
1.6 抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其它类继承的,如果定义为final该类就不能被继承,这样彼此就会产生矛盾,所以final不能修饰抽象类。
2.1 抽象方法
- 如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
- abstract关键字同样可以用来声明抽象方法,抽象方法只包含方法名,而没有方法体。
- 抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
public abstract class Employee{
private String name;
private String address;
private int number;
public abstract double computePay();
}
声明抽象方法会造成以下两个结果:
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。
public class Salary extends Employee{
private double salary;
public double computePay(){
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
本文详细介绍了JAVA面向对象的基本概念,包括封装、继承、多态等核心特性,并解释了面向对象与面向过程的区别,以及如何在JAVA中实现这些特性。
1624

被折叠的 条评论
为什么被折叠?



