【️如何理解面向对象和面向过程】

在这里插入图片描述

✅如何理解面向对象和面向过程?

  • 典型理解
  • ✅扩展知识仓
    • ✅面向对象的三大基本特征
      • ✅封装
      • ✅继承
      • ✅多态
  • ✅为什么Java不支持多继承?
    • ✅菱形继承问题
    • ✅Java 8 中的多继承
  • ✅面向对象的五大基本原则?

典型理解


面向过程把问题分解成一个一个步骤,每个步骤用函数实现,依次调用即可。

我们在进行面向过程编程的时候,不需要考虑那么多,上来先定义一个函数,然后使用各种诸如if-else、for-each等方式进行代码执行。最典型的用法就是实现一个简单的算法,比如实现冒泡排序。


面向对象将问题分解成一人一个步骤,对每个步骤进行相应的抽象,形成对象,通过不同对象之间的调用,组合解决问题。

就是说,在进行面向对象进行编程的时候,要把属性、行为等封装成对象,然后基于这些对象及对象的能力进行业务逻辑的实现。比如想要造一辆车,上来要先把车的各种属性定义出来,然后抽象成一个Car类。

面向对象有封装、继承、多态二大基本特征,和单一职责原则、开放封闭原则、Liskov替换原则、依赖倒置原则和 接口隔离原则等五大基本原则。

✅扩展知识仓

✅面向对象的三大基本特征

三大基本特征:封装继承多态

✅封装

**封装就是把现实世界中的客观事物抽象成一个Java类,然后在类中存放属性和方法。**比如:封装一个汽车类,其中包含了发动机、轮胎、底盘等属性,并且有启动、前进等方法。

//定义一个汽车Car类
public class Car {  
    // 私有变量  
    private String brand; // 品牌  
    private String model; // 型号  
    private int year; // 生产年份  
    private String color; // 颜色  
    private double price; // 价格  
    private Engine engine; // 引擎  
    private Transmission transmission; // 变速器  
    private boolean isOwned; // 是否拥有  
      
    // 构造方法  
    public Car(String brand, String model, int year, String color, double price, Engine engine, Transmission transmission) {  
        this.brand = brand;  
        this.model = model;  
        this.year = year;  
        this.color = color;  
        this.price = price;  
        this.engine = engine;  
        this.transmission = transmission;  
        this.isOwned = false;  
    }  
      
    // 公共方法:获取品牌  
    public String getBrand() {  
        return brand;  
    }  
      
    // 公共方法:设置品牌  
    public void setBrand(String brand) {  
        this.brand = brand;  
    }  
      
    // 公共方法:获取型号  
    public String getModel() {  
        return model;  
    }  
      
    // 公共方法:设置型号  
    public void setModel(String model) {  
        this.model = model;  
    }  
      
    // 公共方法:获取生产年份  
    public int getYear() {  
        return year;  
    }  
      
    // 公共方法:设置生产年份  
    public void setYear(int year) {  
        this.year = year;  
    }  
      
    // 公共方法:获取颜色  
    public String getColor() {  
        return color;  
    }  
      
    // 公共方法:设置颜色  
    public void setColor(String color) {  
        this.color = color;  
    }  
      
    // 公共方法:获取价格  
    public double getPrice() {  
        return price;  
    }  
      
    // 公共方法:设置价格  
    public void setPrice(double price) {  
        this.price = price;  
    }  
      
    // 公共方法:获取引擎对象  
    public Engine getEngine() {  
        return engine;  
    }  
      
    // 公共方法:设置引擎对象  
    public void setEngine(Engine engine) {  
        this.engine = engine;  
    }  
      
    // 公共方法:获取变速器对象  
    public Transmission getTransmission() {  
        return transmission;  
    }  
      
    // 公共方法:设置变速器对象  
    public void setTransmission(Transmission transmission) {  
        this.transmission = transmission;  
    }  
      
    // 公共方法:判断是否拥有该汽车,如果拥有则返回true,否则返回false。在构造函数中,isOwned被设置为false,表示初始状态为未拥有。可以在后续操作中改变其状态。  
    public boolean isOwned() {  
        return isOwned;  
    }  
}

✅继承

像现实世界中儿子可以继承父亲的财产、样貌、行为等一样,编程世界中也有继承,继承的主要目的就是为了复用。子类可以继承父类,这样就可以把父类的属性和方法继承过来。

比如:Dog类,可以继承Animal类,继承过来嘴巴,颜色、等属性,吃东西、奔跑等行为。

// Animal类  
public class Animal {  
    private String name;  
      
    public Animal(String name) {  
        this.name = name;  
    }  
      
    public String getName() {  
        return name;  
    }  
      
    public void setName(String name) {  
        this.name = name;  
    }  
      
    // 抽象方法,需要子类实现  
    public abstract void makeSound();  
}  
  
// Dog类,继承自Animal类  
public class Dog extends Animal {  
    private String breed;  
      
    public Dog(String name, String breed) {  
        super(name); // 调用父类的构造函数  
        this.breed = breed;  
    }  
      
    public String getBreed() {  
        return breed;  
    }  
      
    public void setBreed(String breed) {  
        this.breed = breed;  
    }  
      
    // 实现父类的抽象方法  
    @Override  
    public void makeSound() {  
        System.out.println("汪汪!");  
    }  
}

在这个例子中,Animal类是一个抽象类,定义了一个抽象方法makeSound,它需要由子类来实现。Dog类继承了Animal类,并实现了makeSound方法,因此它是一个具体的类。在Dog类中,我们还添加了一个新的属性breed和一个相应的方法来获取和设置该属性的值。

✅多态

多态是指在父类中定义的方法被子类继承之后,可以通过重写,使得父类和子类具有不同的实现,这使得同一个方法在父类极其各个子类中具有不同的含义。

// 定义一个接口,名为Animal  
public interface Animal {  
    // 定义一个抽象方法,用于发出动物的叫声  
    void makeSound();  
}  
  
// 定义一个类,名为Dog,实现Animal接口  
public class Dog implements Animal {  
    // 重写makeSound方法,实现狗的叫声  
    @Override  
    public void makeSound() {  
        System.out.println("汪汪!");  
    }  
}  
  
// 定义一个类,名为Cat,实现Animal接口  
public class Cat implements Animal {  
    // 重写makeSound方法,实现猫的叫声  
    @Override  
    public void makeSound() {  
        System.out.println("喵喵!");  
    }  
}  
  
// 定义一个类,名为Zoo,包含一个Animal类型的成员变量  
public class Zoo {  
    // 定义一个Animal类型的成员变量,可以是任何实现Animal接口的类对象  
    private Animal animal;  
      
    // 构造函数,接受一个Animal类型的参数,用于初始化animal成员变量  
    public Zoo(Animal animal) {  
        this.animal = animal;  
    }  
      
    // 定义一个方法,让动物发出叫声  
    public void letAnimalMakeSound() {  
        // 使用多态性,调用animal对象的makeSound方法,实现不同的叫声  
        animal.makeSound();  
    }  
}  
  
// 在主函数中测试多态性的实现  
public static void main(String[] args) {  
    // 创建一个Dog对象  
    Dog dog = new Dog();  
    // 使用Dog对象创建一个Zoo对象  
    Zoo zoo = new Zoo(dog);  
    // 调用Zoo对象的letAnimalMakeSound方法,让动物发出叫声  
    zoo.letAnimalMakeSound(); // 输出 "汪汪!"  
      
    // 创建一个Cat对象  
    Cat cat = new Cat();  
    // 使用Cat对象创建一个Zoo对象  
    zoo = new Zoo(cat);  
    // 调用Zoo对象的letAnimalMakeSound方法,让动物发出叫声  
    zoo.letAnimalMakeSound(); // 输出 "喵喵!"  
}

在这个例子中,我们定义了一个Animal接口和两个实现了该接口的类Dog和Cat。我们还定义了一个Zoo类,其中包含一个Animal类型的成员变量。在Zoo类中,我们使用多态性来调用Animal对象的makeSound方法,实现了不同的叫声。在主函数中,我们分别使用Dog和Cat对象创建了两个Zoo对象,并调用了它们的letAnimalMakeSound方法,输出了不同的叫声。

✅为什么Java不支持多继承?

因为如果要实现多继承,就会像C++中一样,存在菱形继承的问题,C++为了解决菱形继承问题,又引入了虚继承。因为支持多继承,引入了菱形继承问题,又因为要解决菱形继承问题,引入了虚继承。而经过分析,人们发现我们其实真正想要使用多继承的情况并不多。所以,在Java 中,不允许“多继承”,即一个类不允许继承多个父类。

除了菱形的问题,支持多继承复杂度也会增加。一个类然承了多个父类,可能会继承大量的属性和方法,导致类的接口变得庞大、难以理解和维护。此外,在修改一个父类时,可能会影响到多个子类,增加了代码的耦合度。

在Java 8以前,接口中是不能有方法的实现的。所以一个类同时实现多个接口的话,也不会出现C++中的歧义问题。因为所有方法都没有方法体,真正的实现还是在子类中的。但是,Java 8中支持了默认函数(defaultmethod),即接口中可以定义一个有方法体的方法了。

而又因为Java支持同时实现多个接口,这就相当于通过implements就可以从多人接口中继承到多人方法了,但是,Java8中为了避免菱形继承的问题,在实现的多个接口中如果有相同方法,就会要求该类必须重写这个方法。

✅菱形继承问题

Java的创始人James Gosling曾经回答过,他表示:

"Java之所以不支持一个类继承多个类,主要是因为在设计之初我们听取了来自C++和Obiective-C等阵营的人的意见。因为多继承会产生很多歧义问题。”

Gosling老人家提到的歧义问题,其实是C++因为支持多继承之后带来的菱形继承问题。

假设我们有类B和类C,它们都继承了相同的类A。另外我们还有类D,类D通过多重继承机制继承了类B和类C.。

在这里插入图片描述
这时候,因为D同时继承了B和C,并且B和C又同时继承了A,那么,D中就会因为多重继承,继承到两份来自A中的属性和方法。

这时候,在使用D的时候,如果想要调用一个定义在A中的方法时,就会出现歧义。

因为这样的继承关系的形状类似于菱形,因此这个问题被形象地称为菱形继承问题。

而C++为了解决菱形继承问题,又引入了虚继承

因为支持多继承,引入了菱形继承问题,又因为要解决菱形继承问题,引入了虚继承。而经过分析,人们发现我们其实真正想要使用多继承的情况并不多。

所以,在Java 中,不允许“声明多继承”,即一个类不允许继承多个父类。但是Java 允许“实现多继承”,即个类可以实现多个接口,一个接口也可以继承多个父接口。由于接口只允许有方法声明而不允许有方法实现(Java 8之前),这就避免了 C++ 中多继承的歧义问题。

✅Java 8 中的多继承

Java不支持多继承,但是是支持多实现的,也就是说,同一个类可以同时实现多个接口。

我们知道,在Java 8以前,接口中是不能有方法的实现的。所以一个类同时实现多个接口的话,也不会出现C++中的歧义问题。因为所有方法都没有方法体,真正的实现还是在子类中的。

💡那么问题来了?

Java 8中支持了默认函数 (default method ),即接口中可以定义一个有方法体的方法了。

public interface Pet {
	public default void eat() {
		System.out.println("Pet Is Eating");
	}
}

而又因为Java支持同时实现多个接口,这就相当于通过implements就可以从多个接口中继承到多人方法了,这不就是变相支持了多继承么。

那么,Java是怎么解决菱形继承问题的呢? 我们再定义一个哺乳动物接口,也定义一个eat方法。

public interface Mammal {
	public default void eat() {
		System.out.println("Mammal Is Eating");
	}
}

然后定义一个Cat,让他分别实现两个接口:

public class Cat implements Pet,Mammal {
	
}

这个时间编译会报错:

error: class Cat inherits unrelated defaults for eat() from types Mammal and Pet

这个时候,就要求Cat类中,必须重写eat()。

public class Cat implements Pet,Mammal {
	@Override
	public void eat()  {
		System.out.println("Cat Is Eating");
	}
}

所以可以看到,Java并没有帮我们解决多继承的歧义问题,而是把这个问题留给开发人员,通过重写方法的方式自己解决。

✅面向对象的五大基本原则?

博客 : 设计模式

五大基本原则: 单一职责原则(Single-Responsibility Principle) 、开放封闭原则(Open-Closedprinciple) 、Liskov替换原则 (Liskov-Substituion Principle) 、依赖倒置原则(Dependency-InversionPrinciple)和接门隔离原则(Interface-Segregation Principle)。

单一职责原则 : 一个类最好只做一件事

开放封闭原则 : 对扩展开放、对修改封闭

里氏替换原则 : 子类必须能够替换其基类

依赖倒置原则 : 程序要依赖于抽象接口,而不是具体的实现

接口隔离原则 : 使用多个小的专门的接口,而不要使用一个大的总接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/251499.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《耦合碳-绿证-消纳量市场的日前电量市场交易交互式优化》

这个标题描述了一种优化模型或算法,用于在日前电量市场中耦合碳排放权市场、可再生能源绿色证书市场和消纳量市场进行交易的交互式优化。我将解析标题的关键词和概念: 日前电量市场:指的是电力市场中进行短期调度和交易的市场,其…

ES6 面试题 | 11.精选 ES6 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

vue-element-admin如何把mock换成使用真实后台接口

1)修改vue.config.js文件 use strict const path require(path) const defaultSettings require(./src/settings.js)function resolve(dir) {return path.join(__dirname, dir) }const name defaultSettings.title || vue Element Admin // page title// If you…

C++相关闲碎记录(15)

1、string字符串 #include <iostream> #include <string> using namespace std;int main (int argc, char** argv) {const string delims(" \t,.;");string line;// for every line read successfullywhile (getline(cin,line)) {string::size_type beg…

带你亲证AI应用开发的“奇点”时刻

带你亲证AI应用开发的“奇点”时刻 AI 应用开发——新的历史节点 事实上&#xff0c;没有任何一种突破能够不经历重重失败&#xff0c;不体验一轮轮的痛苦&#xff0c;就能直接展现在人类面前。AI 技术自诞生之初直至今日&#xff0c;其发展之路从未一帆风顺——辉煌与寒冬交…

SLAM算法与工程实践——相机篇:传统相机使用(1)

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

Leetcode的AC指南 —— 链表:19.删除链表的倒数第N个节点

摘要&#xff1a; Leetcode的AC指南 —— 链表&#xff1a;19.删除链表的倒数第N个节点。题目介绍&#xff1a;给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 文章目录 一、题目二、解析1、滑动窗口/快慢指针&#xff08;傻傻分不清&…

平均数 C语言xdoj66

问题描述 计算n个整数&#xff08;x1,x2,x3...&#xff09;的平均数&#xff0c;结果保留两位小数。 输入说明 第一行为整数n&#xff08;1 < n <100&#xff09;&#xff0c;接下来是n个整数(0 < x1,x2,x3....< 2^31 - 1)。 输出说明 输出这n个整数的…

netty-daxin-2(netty常用事件讲解)

文章目录 netty常用事件讲解ChannelHandler接口ChannelHandler适配器类ChannelInboundHandler 子接口Channel 的状态调用时机ChannelHandler 生命周期示例NettServer&CustomizeInboundHandlerNettyClient测试分析 ChannelInboundHandlerAdapter适配器类SimpleChannelInboun…

C# 如何控制多线程同步执行

写在前面 使用Task类来控制多线程的同步执行&#xff0c;可应用于多任务分发执行后&#xff0c;再做归并处理。Tas既拥有线程池的优点&#xff0c;同时也解决了使用ThreadPool不易控制的弊端&#xff1b;可以非常简便并可靠地实现多线程的顺序执行。 代码实现 public class …

qt中通过objectName来查找控制,使用控件(QString名字)

先拖个控件&#xff0c;名字为label_1,然后执行如下操作&#xff1a; QString objectName QString("label_1");QLabel *tempLabel this->findChild<QLabel*>(objectName);tempLabel->setText("123");

钉钉 × E签宝,打通系统屏障,实现钉钉审批通过后自动同步到E签宝发起签署并返回拖章链接全流程自动化

1 场景描述 成熟的业务体系需要用户的优质体验和高效的交易效率来支撑。而合同作为双方业务往来的法律保证&#xff0c;签合同已成为目前企业必不可少的重要一环。但传统的签署场景中&#xff0c;传统纸质合同的签署往往采用线下见面或邮寄的方式进行&#xff0c;不仅流程复杂&…

C++使用UDP

C使用UDP 对C使用UDP做了简单封装&#xff0c;可直接运行 头文件udp.h #pragma once #include <Winsock.h> #pragma comment(lib,"WS2_32.lib")#define LOCAL_IP_ADDR INADDR_ANY //当前应用程序接收的IP地址 #define LOCAL_PORT 9527 …

【笔试强化】Day 4

文章目录 一、单选1.2.3.4.5.6.7. 二、不定项选择1.2.3. 三、编程1. 计算糖果题解&#xff1a;代码&#xff1a; 2. 进制转换题解&#xff1a;代码&#xff1a; 一、单选 1. 正确答案&#xff1a;D队列先进先出 A&#xff1a;栈有关 B&#xff1a;错 C&#xff1a;错 2. 正确…

二叉树遍历

今天讲的不是 leetcode 上的题&#xff0c;但也和二叉树有关&#xff0c;一道比较有意思的题 牛客网上的题&#xff0c;如果看懂了&#xff0c;也可以来试着做一下&#xff1a; 二叉树遍历_牛客题霸_牛客网 (nowcoder.com) 题目 编一个程序&#xff0c;读入用户输入的一串先…

VGG(pytorch)

VGG:达到了传统串型结构深度的极限 学习VGG原理要了解CNN感受野的基础知识 model.py import torch.nn as nn import torch# official pretrain weights model_urls {vgg11: https://download.pytorch.org/models/vgg11-bbd30ac9.pth,vgg13: https://download.pytorch.org/mo…

WEB 3D技术 简述React Hook/Class 组件中使用three.js方式

之前 已经讲过了 用vue结合three.js进行开发 那么 自然是少不了react 我们 还是先创建一个文件夹 终端执行 npm init vitelatest输入一下项目名称 然后技术选择 react 也不太清楚大家的基础 那就选择最简单的js 然后 我们就创建完成了 然后 我们用编辑器打开创建好的项目目…

卷积的计算 - im2col 2

卷积的计算 - im2col 2 flyfish import numpy as np np.set_printoptions(linewidth200)# F filter kerneldef im2col(images, kernel_size, stride1, padding0):#process imagesif images.ndim 2:images images.reshape(1, 1, *images.shape)elif images.ndim 3:N, I_…

RK3568平台开发系列讲解(Linux系统篇)如何优化Linux驱动的稳定性和效率

🚀返回专栏总目录 文章目录 一、检测 ioctl 命令二、检测传递地址是否合理三、分支预测优化沉淀、分享、成长,让自己和他人都能有所收获!😄 📢在 Linux 中应用程序运行在用户空间,应用程序错误之后,并不会影响其他程序的运行,而驱动工作在内核层,是内核代码的一部分…

响应者链概述

响应者链 iOS事件的3大类型 Touch Events(触摸事件)Motion Events(运动事件&#xff0c;比如重力感应和摇一摇等)Remote Events(远程事件&#xff0c;比如用耳机上得按键来控制手机) 触摸事件 处理触摸事件的两个步骤 寻找事件的最佳响应者事件的响应在响应链中的传递 寻…