第6章.面向对象

面向对象

概述

如今主流的软件开发思想有两种:一个是面向过程,另一个是面向对象。面向过程出现得较早,典型代表为C语言,开发中小型项目的效率很高,但是很难适用于如今主流的大中型项目开发场景。面向对象则出现得更晚一些,典型代表为Java或C++等语言,更加适合用于大型开发场景。两种开发思想各有长短。

对于面向过程的思想:当需要实现一个功能的时候,看中的是每一个步骤怎么做,整体的过程是怎样的。每一个操作都需要自己亲力亲为。

对于面向对象的思想:当需要实现一个功能的时候,不看重具体的过程和步骤是怎样的,而是关心“谁能帮我做这件事情”。(偷懒儿,找人帮我做事儿。)

面向对象的三大特征有:封装性、继承性、多态性。

生活举例

  1. 洗衣服
  • 面向过程(手洗):脱衣服、找一个盆、加水、加洗衣粉、浸泡30分钟、搓洗、拧衣服、倒掉水、再加水、漂洗、拧衣服、倒掉水、晾衣服。

  • 面向对象(机洗):脱衣服、放入洗衣机、按下开关、拿出衣服晾晒。

  1. 买电脑
  • 面向过程(自己买):需要电脑、查询参数信息、横向比较机型、了解打折信息、与店家讨价还价、下单、收快递、开机验货、确认收货。

  • 面向对象(找人买):需要电脑、找秘书帮我买、收电脑。

  1. 吃饭
  • 面向过程(自己做):我饿了、买菜、洗菜择菜、切菜、起火、炒菜、盛菜、吃饭、刷碗。

  • 面向对象(出去买):我饿了、买饭、吃饭。

代码体验

package cn.itcast.day06.demo01;

import java.util.Arrays;

/*
 * 面向过程:
 * 当需要实现一个功能的时候,所有的步骤都要亲力亲为,处理每一个代码细节。
 * 
 * 面向对象:
 */
public class Demo01PrintArray {
    
    public static void main(String[] args) {
        int[] array = { 10, 20, 30, 40, 50 };
        
        // 首先使用面向过程的思想,每一个步骤细节都要亲自处理
        System.out.print("[");
        for (int i = 0; i < array.length; i++) {
            if (i == array.length - 1) {
                System.out.println(array[i] + "]");
            } else {
                System.out.print(array[i] + ", ");
            }
        }
        
        System.out.println("==================");
        
        // 使用面向对象的思想,达到同样的效果。
        // 自己不处理详细的步骤,而是找人帮我做事儿。
        // 在JDK当中已经给我们提供好了一个工具,叫做Arrays
        // 通过这个工具就可以将数组转换成为指定格式的字符串
        
        // 我自己不做,而是找Arrays帮我把数组转换成为指定格式的字符串
        System.out.println(Arrays.toString(array));
    }

}

类与对象的关系

我们学习编程语言,就是为了模拟现实世界中的事物,实现信息化来提高工作效率。例如银行的业务系统、超市的结账系统等,都是如此。那么现实世界的事物通常分成两个组成部分:

  1. 属性:事物的特征描述信息,“是什么”。

  2. 行为:事物的能力行动方案,“能做什么”。

面向对象的语言当中,“类”就是用来模拟现实事物的。类中也有属性、行为两个组成部分,而“对象”是类的具体实例。例如:

  1. :抽象的,是一张“手机设计图”。

  2. 对象:具体的,是一个“真正的手机实例”。

类的定义

类是用来模拟现实事物的代码手段,事物分成属性、行为两个部分,类当中也对应地包含两个部分:

  1. 成员变量(属性):将变量位置直接定义在类中,在方法外,即为成员变量。

  2. 成员方法(行为):将普通的方法去掉static关键字,即为成员方法。

public class Student {
    
    // 成员变量
    String name; // 姓名
    int age; // 年龄
    
    // 成员方法
    public void eat() {
        System.out.println("吃饭饭!");
    }
    
    public void sleep() {
        System.out.println("睡觉觉!");
    }
    
    public void study() {
        System.out.println("学习!");
    }

}

创建对象

类如同一张设计图纸,通常情况下不能直接使用;要想使用,则需要根据类创建一个真正的对象,然后使用对象中的功能。根据类创建对象的格式为:

类名称 对象名 = new 类名称();

public class Demo02Student {
    
    public static void main(String[] args) {
        // 希望根据Student类来创建一个学生对象
        // 格式:类名称 对象名 = new 类名称();
        // 创建一个对象,是一个学生,对象名称叫stu1
        // 对象的名称stu1也叫做对象的“引用名”。
        Student stu1 = new Student();
        Student stu2 = new Student(); // 创建了第二个对象
        Student stu3 = new Student(); // 创建更多学生对象
        Student stu4 = new Student(); // 创建更多学生对象
        Student stu5 = new Student(); // 创建更多学生对象
        
    }

}

对象的基本使用

对象是根据类创建出来的,所以内部包含成员变量、成员方法两个组成部分。使用它们的格式如下:

  1. 使用成员变量:对象名.成员变量名

  2. 调用成员方法:对象名.成员方法名(参数)

简单来说,“想用谁就点儿谁”。

public class Demo03Student {
    
    public static void main(String[] args) {
        Student stu = new Student(); // 创建了一个学生对象
        
        System.out.println(stu.name); // null
        System.out.println(stu.age); // 0
        System.out.println("==============");
        
        // 改变成员变量的数据值
        stu.name = "鹿晗";
        stu.age = 20;
        System.out.println(stu.name); // 鹿晗
        System.out.println(stu.age); // 20
        System.out.println("==============");
        
        // 将对象当中的成员变量,交给name变量
        String name = stu.name;
        System.out.println(name); // 鹿晗
        System.out.println("==============");
        
        // 使用对象当中的成员方法
        stu.eat(); // 调用吃饭的成员方法
        stu.sleep(); // 调用睡觉的成员方法
        stu.study(); // 调用学习的成员方法
    }

}

对象的内存图

一个对象

对象的名称其实就是一个局部变量,里面存放的是地址值。真正new出来的对象在堆内存当中,而且成员方法保存的是方法区中的地址。

两个对象

两个对象的情况与一个对象是类似的,对象名称作为局部变量保存地址值,对象中的成员方法是方法区中的地址值。

同一个对象

如果使用“Phone two = one;”的代码写法,那么是将one当中的地址值赋值给two,于是one和two的地址相同,指向了同一个对象。

区分局部变量与成员变量

  1. 定义的位置不同:

a) 局部变量定义在方法内

b) 成员变量定义在方法外,直接在类中

  1. 内存的位置不同:

a) 局部变量是在栈内存中的

b) 成员变量是在堆内存中的

  1. 生命周期不同:

a) 局部变量随着方法进栈而出现,随着方法出栈而消失

b) 成员变量随着对象被创建而出现,随着对象被回收而消失

  1. 默认值不同:

a) 局部变量没有默认值,必须赋值之后才能使用

b) 成员变量如果没有赋值,那么会有默认值

private关键字

如果类当中有一些成员不希望被外界直接访问,那么可以使用private关键字进行修饰,从而达到确保数据安全的目的。

private关键字是面向对象三大特征(封装、继承、多态)之一封装性的重要体现。

public class Person {
    
    // 成员变量
    String name; // 姓名
    private int age; // 年龄
    
    // 成员方法
    public void show() {
        System.out.println("我叫" + name + ",今年" + age + "岁。");
    }
    
    // 专门定义了一个成员方法用来设置成员变量的数据,Setter方法
    public void setAge(int num) {
        // 设置条件判断进行数据合理性检测,把关!
        if (num < 0 || num > 200) {
            System.out.println("数据错误!");
        } else {
            age = num;
        }
    }
    
    // 专门定义了一个成员方法用来获取成员变量的数据,Getter方法
    public int getAge() {
        return age;
    }

}

this关键字

如果成员变量和局部变量重名,那么方法中会根据就近原则优先使用局部变量。此时可以通过this关键字进行二者的区分:

this.成员变量名

public class Person {
    
    String name; // 我自己的名字
    
    public void sayHello(String name) { // 对方的名字
        System.out.println(name + ",你好。我是" + this.name + "。");
    }

}

构造方法

构造方法是指在类当中专门用于创建对象的方法,定义格式:

修饰符 构造方法名(参数类型 参数名称) {

方法体

// return; // 最后一行return通常省略

}

当通过new关键字创建对象的时候,实际上就是在调用构造方法。

注意事项

  1. 构造方法根本不写返回值类型,连void都不写。

  2. 构造方法的名称和所在的类名称必须完全一样,连大小写都要一样

  3. 构造方法也是可以进行重载的。

  4. 构造方法如果没有自定义,那么将会默认赠送一个。如果自定义了至少一个,那么就不再赠送默认的。

练习:两个对象的邂逅

定义一个类代表“人”,含有姓名和年龄,而且具有打招呼的功能。根据类创建两个对象并且赋值。让两个对象分别和对方打招呼。

知识总结

  1. 面向过程:当需要实现一个功能的时候,每一个过程中的详细步骤和细节都要亲力亲为。

  2. 面向对象:当需要实现一个功能的时候,不关心详细的步骤细节,而是找人帮我做事儿。

  3. 类和对象的关系:

   a) 类是抽象的,通常不能直接使用。好像是一张手机设计图纸。

   b) 对象是具体的,根据类创建一个对象使用,也就是根据图纸创造一个手机。

  1. 如何定义一个类:成员变量、成员方法。

   a) 成员变量:直接定义在类当中,在方法外面。

   b) 成员方法:去掉static关键字,其他和此前的普通方法一样。

  1. 如何根据类创建对象,格式:类名称 对象名 = new 类名称();

  2. 如何使用对象:

   a) 使用成员变量:对象名.成员变量名

   b) 调用成员方法:对象名.成员方法名(参数)

  1. 局部变量和成员变量的不同:

   a) 定义的位置不同

   b) 内存的位置不同

   c) 生命周期不同

   d) 默认值不同

  1. private关键字用法:直接写在成员变量前面,类外面不能直接访问,确保安全性。间接访问:编写一对儿Getter Setter方法。(特例:如果是boolean类型,getXxx必须叫做isXxx的形式。)

  2. this关键字典型用法:用来区分同名的成员变量和局部变量。在成员变量的前面写上“this.”前缀即可。

  3. 构造方法:专门用来创建对象的方法,通过new关键字创建对象就是在调用构造。

   a) 构造方法不能写返回值类型,连void都不能写。

   b) 构造方法的名称必须和所在的类名称完全一样,大小写也要一样。

   c) 构造方法也是可以重载的。

   d) 构造方法如果没有定义,默认送一个;如果定义了,那么默认的不再赠送。

  1. 如何定义一个标准的POJO类:

   a) 所有的成员变量都用private修饰

   b) 为每一个成员变量编写一对儿Getter Setter方法

   c) 编写一个无参数的构造方法

   d) 编写一个全参数的构造方法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352