JAVA面向对象

一、面向过程&面向对象

面向对象是基于面向过程这一概念产生而来的,因此要了解面向对象,首先得了解什么是面向过程。

什么是面向过程?

面向过程侧重于按顺序执行一系列步骤,强调函数(方法)和数据的分离,使用过程和函数来完成任务。与面向对象编程相比,缺乏抽象和封装,更直接地解决问题。

例如:

public class A{
    public static int countArea(int height,int width){
        return height*width;
    }
    
    public static void main(String[] args){
        int height = 2;
        int width = 3;
        //长方形面积为:6
        System.out.println("长方形面积为:"+countArea(height,width));
    }
}

什么是面向对象?

通过模块化的对象,将数据和操作数据的方法封装在一起。核心思想包括类与对象的概念、封装、继承、多态,提供了更灵活、可维护的代码结构。

例如:

public class Rectangle{
    private int height = 2;
    private int width = 3;

    public Rectangle(int height,int width){
        this.height = height;
        this.width = width;
    }

    public void setHeight(int height){
        this.height = height;
    }
    
    public void setWidth(int width){
        this.width = width;
    }

    public int countArea(){
        return height*width;
    }
}

public class B{
    public static void main(String[] args){
        Rectangle r = new Rectangle(2,3);
        //长方形面积为:6
        System.out.println("长方形面积为:"+r.countArea());
    }
}

单单从简单的例子可能并不容易看出面向对象编程的好处,设想:涉及到复杂的开发时,面向过程的编程仅仅数据与方法的分离就会产生许多问题,例如代码的可读性低,难以维护等,为了能够解决面向过程开发中存在的一系列问题,掌握面向对象的开发思想是一名开发者必备的。

二、面向对象的三大特性

2.1 封装

封装是将对象的状态(属性)和行为(方法)打包在一起,并对外部隐藏内部实现细节。通过访问修饰符限制对对象内部的直接访问,提高了代码的安全性和可维护性。可以参考以上Rectangle类的例子。

2.2 继承

继承允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以重用父类的代码,同时可以进行扩展或修改,提高了代码的重用性和可扩展性。

例如:车辆都有点火"启动"和"熄火"的行为,因此创建一个父类Vehicle。卡车能"运货"、大巴能"运人",大巴与卡车又属于车辆,因此子类又有自己独有的方法,而子类继承父类就不需要多次重复写"启动"和"熄火"这两个方法。

public class Vehicle {
    public void start() {
        System.out.println("车辆启动...");
    }

    public void stop() {
        System.out.println("车辆停止...");
    }
}

public class Truck extends Vehicle {
    private String brand;

    public Truck(String brand) {
        this.brand = brand;
    }

    public void shipping() {
        System.out.println("卡车:" + brand + " 正在运货...");
    }
}

2.3 多态

多态指的是一个对象可以以多种形式呈现。在编译时多态中,通过方法的重载实现;而在运行时多态中,通过方法的重写和接口实现。多态提高了代码的灵活性和可维护性,使得同一接口可以有不同的实现。

例如:要实现画图工具类,先定义一个接口Shape,所有的实现类都要实现draw方法进行画图,但是draw方法的具体实现各不相同,因此这个draw抽象方法不需要方法体,具体实现由实现类来给出。在使用时,用父类Shape声明参数类型,而后直接调用draw方法,具体调用哪个实现类则由new或其他方式给出,降低了代码的耦合度。

// 接口
public interface Shape {
    void draw();
}

// 具体实现类
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("画了一个圆...");
    }
}

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("画了一个正方形...");
    }
}

// 使用多态
public class DrawingProgram {
    public static void main(String[] args) {
        Shape shape1 = new Circle();
        Shape shape2 = new Square();

        shape1.draw();  // 调用的是 Circle 类的 draw 方法
        shape2.draw();  // 调用的是 Square 类的 draw 方法
    }
}

三、面向对象设计的基本原则

面向对象设计有一些重要的原则,这些原则帮助开发者创建灵活、可维护、可扩展的软件系统。以下是其中一些常见的原则:

  1. 单一职责原则(Single Responsibility Principle - SRP): 一个类应该只有一个引起变化的原因。换句话说,一个类应该只有一个职责。这有助于保持类的简单性和可维护性。

  2. 开放-封闭原则(Open-Closed Principle - OCP): 软件实体(类、模块、函数等)应该对扩展是开放的,但对修改是封闭的。通过增加新的代码而不修改已有代码,实现对系统的扩展。

  3. 里氏替换原则(Liskov Substitution Principle - LSP): 子类型必须能够替换掉它们的基类型。在使用继承时,子类应该能够替代其基类而不影响程序的正确性。

  4. 依赖倒置原则(Dependency Inversion Principle - DIP): 高层模块不应该依赖于底层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。通过依赖注入和接口等方式,实现松耦合。

  5. 接口隔离原则(Interface Segregation Principle - ISP): 不应该强迫一个类实现它不需要的接口。客户端不应该被迫依赖它们不使用的方法。

  6. 合成/聚合复用原则(Composition/Aggregation Reuse Principle - CARP): 优先使用合成/聚合而不是继承。通过组合现有的对象,而不是通过继承类来实现代码的重用。

  7. 迪米特法则(Law of Demeter - LoD,又称最少知识原则): 一个对象应该对其他对象有最少的了解。一个类不应该直接调用其他类的内部方法,而是通过中介者或者委托来实现。

这些原则一起帮助开发者设计出符合良好设计原则的、易于维护和扩展的面向对象系统。这些原则通常被称为 SOLID 原则,其中 SOLID 分别代表了这些原则的首字母。

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值