2022-7-18/19 第七组 面向对象
一、了解面向对象
1.概述
- 面向对象(Object Oriented)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,是
- 一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。面向对象是相对于面向过程来讲的,指的是把 相关的数据和方法组织为一个整体 来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。
- 面向过程到面向对象思想层面的转变: 面向过程关注的是执行的过程,面向对象关注的是具备功能的对象。
- 面向过程到面向对象,是程序员思想上 从执行者到指挥者的转变。
2.面向对象与面向过程的区别
- 例子:
下面我们举个例子,比如开车、加速、减速、刹车。
用面向过程来说就是你要先有一个车,然后这四个分别是4件事,也就是说你要写4个函数,分别是开车、加速、减速、刹车,这分别是四个事件,如果使用的话要调用4个函数。
但是对于面向对象的编程来说,我们关心的是车这个类,而不是开车、加速、减速和刹车这四个过程。这4个过程是车这个类的一部分,只是其中的一种行为,而且对于行为的顺序没有强制要求。
- 两种思想的对比:
面向过程是具体的东西,而且面向过程是面向对象的基础。面向对象可以说是面向过程的抽象,比如汽车有开车,加减速和刹车,关于汽车的操作有好多,每一个都需要一个具体的过程来实现,把这些过程抽象的总结起来就可以形成一个类,这个类包括的汽车所有的东西,所有的操作。
总结来说就是,面向过程是一种基础的方法,它考虑的是实际的实现,一般情况下,面向过程是自顶向下逐步求精,其最重要的是模块化的思想方法。因此在模块化编程的时候才会有“低耦合,高内聚”的思想来提高效率。面向对象的方法主要是把事物给对象化,包括其属性和行为。当程序较小的时候,面向过程就会体现出一种优势,其程序流程十分清楚。但是,面向对象编程更贴近实际生活的思想。
- 面向过程和面向对象的本质理解
面向过程是具体化的,流程化的。解决一个问题,需要一步一步分析需要怎样,然后需要怎样,一步一步实现的。面向对象是模型化的,抽象出一个类,这是一个封闭的环境,在这个环境中有数据有解决问题的方法,你如果需要什么功能直接使用就可以了,至于是怎么实现的,你不用知道。
从代码层面来看,面向对象和面向过程的主要区别就是数据是单独存储还是与操作存储在一起。在类的里边,实现具体的功能还是需要流程化、具体化的代码去实现的,在类里还是需要具体的算法来实现的。总结来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象。
3.特点
封装性:所有的内容对外部不可见
继承性:将其他的功能继承下来继续发展
多态性:方法的重载本身就是一个多态性的体现
二、类与对象
1. 什么是类
1、类是:分类、类别。
2、通过分类、我们可以区分不同的事物种类。
3、类具有一种相同特性(属性)与行为(方法)的事物集合。
2.类与对象的关系
1、类表示一个共性的产物:是一个综合的特性,而对象是一个个性的产物,是一个个体的特征。
2、类由属性和方法组成:
属性:就相当于一个个特征。
方法:就相当于人的一个个的行为,例如:吃饭、唱歌、睡觉。
3.类的构成
class 类名称{
成员属性
成员方法
}
public class Car {
// 成员变量
//车的品牌
String brand;
//车的颜色
String color;
//车的长度
long length;
//定义一个成员方法
/*
* public: 返回权限修饰符
* void :没有返回值
* run():方法名
* {} :方法体
* () :传参数
* */
public void run(int gasoline){
System.out.println("在漂移!");
}
}
4.对象的定义和使用
一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
类名称 对象名称 = new 类名称() ;
如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:
访问类中的属性: 对象.属性 ;
调用类中的方法: 对象.方法(实际参数列表) ;
public class Ch02 {
public static void main(String[] args) {
//根据图纸去造车
//创建对象的过程,对象又叫类的一个实例
//我们创建了一个Car类的对象car1
//car1就是对象的名
//其实这个car1就是个标识符
//对象的命名方式:小驼峰
//创建对象的语法:
Car car1 = new Car();
//给车的属性赋值:
car1.brand = "奥迪";
car1.color = "白色";
car1.length = 1800L;
}
}
三、构造方法
1.什么是构造方法
1、构造方法就是类构造对象时调用的方法,用于对象的初始化工作
2、构造方法是实例化一个类的对象时、也就是new的时候,最先调用的方法
2.代码举例
//无参的构造方法
public Dog(){
}
//带一个参数的构造方法:
public Dog(String name){
this.name = name;
}
//带多个参数的构造方法:
public Dog(String name,int age){
this.name = name;
this.age = age;
}
语法:访问权限修饰符 类名(参数列表){ }
3.特点(特性):
1.Java在new对象的时候,先看对象所对应的类有没有构造器,有的话有什么样的构造器;如果没有构造器,则无法构建对象(创建对象)
2.每个类会有一个默认的无参的构造器
3.在对象被实例化时调用了构造器
4.我们创建对象实际上是通过构造器创建的
5.如果一个类中显示的声明了一个构造器,原来默认自带的无参构造器就失效(被覆盖)。如果有多个构造器,必须重载。
四、封装
1.封装思想
1.封装概述
是面向对象三大特征之一(封装,继承,多态)
是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
2.封装原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
成员变量private,提供对应的getXxx()/setXxx()方法
3.封装好处
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性
2.private关键字
private是一个修饰符,可以用来修饰成员(成员变量,成员方法)
被private修饰的成员,只能在本类进行访问,针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
private int username;
private int password;
提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰
public int getUsername() {
return username;
}
public void setUsername(int username) {
this.username = username;
}
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
3.详解this关键字
- this是指当前对象自己。
public class ThisDemo {
String name = "Mick";
public void print(String name) {
System.out.println("类中的属性 name=" + this.name);
System.out.println("局部传参的属性=" + name);
}
public static void main(String[] args) {
ThisDemo tt = new ThisDemo();
tt.print("Orson");
}
}
- 使用this区分同名变量。
public class Demo {
public String name;
public int age;
public Demo(String name, int age) {
this.name = name;
this.age = age;
}
public void say() {
System.out.println(name + " " + age);
}
public static void main(String[] args) {
Demo obj = new Demo("hdk1993", 21);
obj.say();
}
}
- 使用this调用构造函数。
public class Flower {
Flower(int petals) {
}
Flower(String ss) {
}
Flower(int petals, Sting ss) {
// petals++;调用另一个构造函数的语句必须在最起始的位置
this(petals);
// this(ss);会产生错误,因为在一个构造函数中只能调用一个构造函数
}
}
- this作为函数返回值
public class Flower {
int number;
ThisDemo increment() {
number++;
return this;
}
private void print() {
System.out.println("number=" + number);
}
public static void main(String[] args) {
ThisDemo tt = new ThisDemo();
tt.increment().increment().increment().print();
}
}
- this作为参数传递
public class Demo {
public static void main(String[] args) {
B b = new B(new A());
}
}
class A {
public A() {
new B(this).print(); // 匿名对象
}
public void print() {
System.out.println("Hello from A!");
}
}
class B {
A a;
public B(A a) {
this.a = a;
}
public void print() {
a.print();
System.out.println("Hello from B!");
}
}
运行结果:
Hello from A!
Hello from B!
在这个例子中,对象A的构造函数中,用new B(this)把对象A自己作为参数传递给了对象B的构造函数。匿名对象就是没有名字的对象。如果对象只使用一次,就可以作为匿名对象,代码中 new B(this).print(); 等价于 ( new B(this) ).print();,先通过 new B(this) 创建一个没有名字的对象,再调用它的方法。
- 注意匿名类和内部类中的中的this。有时候,我们会用到一些内部类和匿名类,如事件处理。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。
public class A {
int i = 1;
public A() {
Thread thread = new Thread() {
public void run() {
for (;;) {
A.this.run();
try {
sleep(1000);
} catch (InterruptedException ie) {
}
}
}
}; // 注意这里有;
thread.start();
}
public void run() {
System.out.println("i = " + i);
i++;
}
public static void main(String[] args) throws Exception {
new A();
}
}
在上面这个例子中, thread 是一个匿名类对象,在它的定义中,它的 run 函数里用到了外部类的 run 函数。这时由于函数同名,直接调用就不行了。这时有两种办法,一种就是把外部的 run 函数换一个名字,但这种办法对于一个开发到中途的应用来说是不可取的。那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类的方法 run。