Java 的四个主要面向对象编程概念
面向对象编程通常被称为 OOPS,它是Java的支柱,因为Java是一种完全面向对象的语言。 Java围绕各种对象和定义良好的接口组织程序。 OOPS 中有四个支柱,如下所列。这些概念旨在在程序中实现真实世界的实体。
- 抽象
- 封装
- 遗产
- 多态性
抽象是隐藏实现细节并且只向用户公开功能的过程。抽象地说,我们处理的是想法而不是事件。这意味着用户只会知道“它做了什么”而不是“它是如何做的”。
Java有两种实现抽象的方式
- 抽象类(0 到 100%)
- 界面 (100%)
Real-Life Example: A driver will focus on the car functionality (Start/Stop -> Accelerate/ Break), he/she does not bather about how the Accelerate/ brake mechanism works internally. And this is how the abstraction works.
关于 OOPS 的这一支柱,应记住以下关键点:
- 如果一个类有一个或多个抽象方法,则该类应该是抽象的
- 抽象类可以有构造函数、具体方法、静态方法和最终方法
- 抽象类不能直接用new 运算符实例化。如下面的 pre 标签所示:
A b = new B();
- 子类应该覆盖父类的所有抽象方法,否则子类应该用abstract关键字声明
例子:
Java
// Abstract class
public abstract class Car {
public abstract void stop();
}
// Concrete class
public class Honda extends Car {
// Hiding implementation details
@Override public void stop()
{
System.out.println("Honda::Stop");
System.out.println(
"Mechanism to stop the car using break");
}
}
public class Main {
public static void main(String args[])
{
Car obj
= new Honda(); // Car object =>contents of Honda
obj.stop(); // call the method
}
}
Java
// A Java class which is a fully encapsulated class.
public class Car
{
// private variable
private String name;
// getter method for name
public String getName()
{
return name;
}
// setter method for name
public void setName(String name)
{
this.name = name
}
}
// Java class to test the encapsulated class.
public class Test
{
public static void main(String[] args)
{
// creating instance of the encapsulated class
Car car
= new Car();
// setting value in the name member
car.setName("Honda");
// getting value of the name member
System.out.println(car.getName());
}
}
Java
// super class
class Car {
// the Car class have one field
public String wheelStatus;
public int noOfWheels;
// the Car class has one constructor
public Car(String wheelStatus, int noOfWheels)
{
this.wheelStatus = wheelStatus;
this.noOfWheels = noOfWheels;
}
// the Car class has three methods
public void applyBrake()
{
wheelStatus = "Stop" System.out.println(
"Stop the car using break");
}
// toString() method to print info of Car
public String toString()
{
return ("No of wheels in car " + noOfWheels + "\n"
+ "status of the wheels " + wheelStatus);
}
}
// sub class
class Honda extends Car {
// the Honda subclass adds one more field
public Boolean alloyWheel;
// the Honda subclass has one constructor
public Honda(String wheelStatus, int noOfWheels,
Boolean alloyWheel)
{
// invoking super-class(Car) constructor
super(wheelStatus, noOfWheels);
alloyWheel = alloyWheel;
}
// the Honda subclass adds one more method
public void setAlloyWheel(Boolean alloyWheel)
{
alloyWheel = alloyWheel;
}
// overriding toString() method of Car to print more
// info
@Override public String toString()
{
return (super.toString() + "\nCar alloy wheel "
+ alloyWheel);
}
}
// driver class
public class Main {
public static void main(String args[])
{
Honda honda = new Honda(3, 100, 25);
System.out.println(honda.toString());
}
}
Java
public class Car{
public void speed() {
}
public void speed(String accelerator) {
}
public int speed(String accelerator, int speedUp) {
return carSpeed;
}
}
Java
import java.util.Random;
class DeliveryBoy {
public void deliver() {
System.out.println("Delivering Item");
}
public static void main(String[] args) {
DeliveryBoy deliveryBoy = getDeliveryBoy();
deliveryBoy.deliver();
}
private static DeliveryBoy getDeliveryBoy() {
Random random = new Random();
int number = random.nextInt(5);
return number % 2 == 0 ? new Postman() : new FoodDeliveryBoy();
}
}
class Postman extends DeliveryBoy {
@Override
public void deliver() {
System.out.println("Delivering Letters");
}
}
class FoodDeliveryBoy extends DeliveryBoy {
@Override
public void deliver() {
System.out.println("Delivering Food");
}
}
支柱 2:封装
封装是将代码和数据一起包装成一个单元的过程。
Real-Life Example:
A capsule which is mixed of several medicines. The medicines are hidden data to the end user.
为了在Java实现封装,请遵循以下建议的某些步骤:
- 将变量声明为私有
- 声明 setter 和 getter 来设置和获取变量值
Note: There are few disadvantages of encapsulation in java as follows:
- Control Over Data: We can write the logic in the setter method to not store the negative values for an Integer. So by this way we can control the data.
- Data Hiding: The data members are private so other class can’t access the data members.
- Easy to test: Unit testing is easy for encapsulated classes
例子:
Java
// A Java class which is a fully encapsulated class.
public class Car
{
// private variable
private String name;
// getter method for name
public String getName()
{
return name;
}
// setter method for name
public void setName(String name)
{
this.name = name
}
}
// Java class to test the encapsulated class.
public class Test
{
public static void main(String[] args)
{
// creating instance of the encapsulated class
Car car
= new Car();
// setting value in the name member
car.setName("Honda");
// getting value of the name member
System.out.println(car.getName());
}
}
支柱 3:继承
继承是Java中一个类从另一个类继承属性和方法的过程。当我们在对象之间有is-a关系时使用继承。 Java的继承是使用extends关键字实现的。
Real-life Example:
The planet Earth and Mars inherits the super class Solar System and Solar system inherits the Milky Way Galaxy. So Milky Way Galaxy is the top super class for Class Solar System, Earth and Mars.
在提出代码之前,让我们通过一个通用示例来讨论Java应用程序中继承的用法。因此,请考虑扩展 Exception 类以创建包含更多信息(如错误代码)的特定于应用程序的 Exception 类的示例。例如 NullPointerException。
Java有5种不同的继承类型,如下所示:
- 单一继承: B 类使用 extends 关键字继承 B 类
- 多级继承: C类继承B类,B类使用extends关键字继承A类
- 层次结构继承: B 类和 C 类使用 extends 关键字按层次结构顺序继承类 A
- 多重继承: C 类继承了 A 类和 B 类。这里 A 和 B 都是超类,C 只是一个子类。 Java不支持多重继承,但我们可以使用接口来实现。
- Hybrid Inheritance: D类继承B类和C类,B类和C类继承A。这里同样D类继承了两个超类,所以Java也不支持Hybrid Inheritance。
例子:
Java
// super class
class Car {
// the Car class have one field
public String wheelStatus;
public int noOfWheels;
// the Car class has one constructor
public Car(String wheelStatus, int noOfWheels)
{
this.wheelStatus = wheelStatus;
this.noOfWheels = noOfWheels;
}
// the Car class has three methods
public void applyBrake()
{
wheelStatus = "Stop" System.out.println(
"Stop the car using break");
}
// toString() method to print info of Car
public String toString()
{
return ("No of wheels in car " + noOfWheels + "\n"
+ "status of the wheels " + wheelStatus);
}
}
// sub class
class Honda extends Car {
// the Honda subclass adds one more field
public Boolean alloyWheel;
// the Honda subclass has one constructor
public Honda(String wheelStatus, int noOfWheels,
Boolean alloyWheel)
{
// invoking super-class(Car) constructor
super(wheelStatus, noOfWheels);
alloyWheel = alloyWheel;
}
// the Honda subclass adds one more method
public void setAlloyWheel(Boolean alloyWheel)
{
alloyWheel = alloyWheel;
}
// overriding toString() method of Car to print more
// info
@Override public String toString()
{
return (super.toString() + "\nCar alloy wheel "
+ alloyWheel);
}
}
// driver class
public class Main {
public static void main(String args[])
{
Honda honda = new Honda(3, 100, 25);
System.out.println(honda.toString());
}
}
支柱 4: Java的多态性
多态性是一种以多种方式执行多种操作的能力。多态这个词来自两个不同的希腊词——poly 和 morphs。 “Poly”表示许多,“Morphs”表示形式。所以多态意味着多种形式。在继承的情况下也可以存在多态性。这些函数的行为因实际实现而异。
Real-life Example:
A delivery person delivers items to the user. If it’s a postman he will deliver the letters. If it’s a food delivery boy he will deliver the foods to the user. Like this polymorphism implemented different ways for the delivery function.
下面列出了两种类型的多态性:
- 静态或编译时多态性
- 动态或运行时多态性
当编译器能够确定实际函数,静态或编译时多态称为编译时多态。编译时多态可以通过Java的方法重载来实现。当一个类中的不同函数具有相同的名称但具有不同的签名时,称为方法重载。方法签名包含名称和方法参数。因此,重载方法具有不同的参数。参数可能在数量或参数类型上有所不同。
示例 1:静态多态
Java
public class Car{
public void speed() {
}
public void speed(String accelerator) {
}
public int speed(String accelerator, int speedUp) {
return carSpeed;
}
}
当编译器无法确定它是超类方法还是子类方法时,就会发生动态或运行时多态性,这称为运行时多态性。运行时多态性是通过方法覆盖实现的。在子类中重写超类方法时,称为方法重写。
示例 2:动态多态
Java
import java.util.Random;
class DeliveryBoy {
public void deliver() {
System.out.println("Delivering Item");
}
public static void main(String[] args) {
DeliveryBoy deliveryBoy = getDeliveryBoy();
deliveryBoy.deliver();
}
private static DeliveryBoy getDeliveryBoy() {
Random random = new Random();
int number = random.nextInt(5);
return number % 2 == 0 ? new Postman() : new FoodDeliveryBoy();
}
}
class Postman extends DeliveryBoy {
@Override
public void deliver() {
System.out.println("Delivering Letters");
}
}
class FoodDeliveryBoy extends DeliveryBoy {
@Override
public void deliver() {
System.out.println("Delivering Food");
}
}
Delivering Letters