Java从零开始 第6讲 类与对象

什么是面向对象

面向对象(Object Oriented)是一种抽象的思考方法,并不拘泥于计算机技术。

面向过程(C语言就是面对过程的语言),关注的是执行的过程;而面向对象,则是关注具备执行该过程的对象。从面向过程到面向对象,是在思想上从执行者到指挥者的转变。
以上的概念可能不好理解,让我们用一个例子来说明:

小明开了一家杂货铺,这时有人来买东西

面向过程:购买者说想要一包薯片,小明说价格,付钱,小明给他薯片。
面向对象:小明招聘一个收银员,教他如果购买者想要买一包薯片,就说出薯片的价格,付了钱之后给他薯片

此时看来,面向对象似乎比面向过程更复杂,但是当我们更改一下例子,小明开了一家连锁杂货铺,分布在全国各地,开了数百家,这时小明还能面向过程吗?

在代码的世界也是如此,在少量的代码时,面向过程更简单,但是当代码量变大,重复过程变多的时候,面向对象则是更好的选择。

面对对象的思想从概念上可以分为三类:

  • OOA:面对对象分析,Object Oriented Analysis
  • OOD:面对对象设计,Design
  • OOP:面对对象编程,Programming

面对对象也有三个主要特征:封装性,继承性,和多态性(会在以后小节中详细讲解)

类与对象

类(class)表示一个共性的产物,是一个综合特征的集合;而对象(object)则是一个单独的个体,对象的特征是个体的特征。

让我们用一个例子来说明:人类即是一个类,用来描述所有的人,你可以说人类是哺乳动物,是灵长类动物,大多有一双眼睛,两条腿,这些就是人类的特征。而人类中的一个对象就是一个单独的人,小明就是人类的一个对象,小明符合人类的特征,但可能还有自己特殊的特征,例如小明长得很帅,小明身高八尺有余,这些都是小明自己的特征,而不是人类的特征。

一个类必须通过对象才可以使用,但是对象的所有操作都需要在类中定义。类由属性和方法组成,属性就相当于类的特征,方法则相当于对象可以进行的行为。

让我们同样用人类来举例:人类的属性就是人是哺乳动物,是灵长类动物,方法则包括吃饭,说话,睡觉。当你想要使用这些方法时,你不能直接用类,而是需要一个对象,比如小明吃饭,小明说话,而且你创建的对象小明一定会满足人类的属性,即小明一定是哺乳动物,是灵长类动物。

特别提示:其中用类创建对象的过程被称为实例化instantiation,在之前的输入中曾经使用过)

类与对象的创建

class类一般通过如下方式定义


class 类名称{
    成员属性;
    成员方法;
}

让我们看看我们最早写的第一个程序Hello World


public class HelloWorld {

    public static void main(String[] args){

        System.out.println("Hello World!");

    }
}

其中不难发现我们定义了一个类,类的名字叫做HelloWorld,且类的前面有一个public来修饰(目前阶段仅了解,你只需要知道,一个java文件中可以存在若干个类,但只能存在一个public类,且public类的类名需要跟java文件名一样),类中没有成员属性,存在一个成员方法,方法名为main(为程序的入口方法)。

现在让我们目光锁定到方法上,类中的方法通过如下形式定义


返回值类型 方法名称(形式参数列表){
    方法体;
    return 返回值;
}

其中,返回值类型为需要返回的值的类型,方法名称就是调用该方法需要使用的名称,形式参数列表就是该方法需要传入的参数的列表。

让我们用一个简单的类来举例:


class Preson{// 直接放在public类下面

    String name;
    int age;
    int height;// 这里是成员属性

    // 以下是三种方法
    String getName(){
        return name;// 直接返回成员属性name
    }
    
    int getBirthYear(int currentYear){
        return currentYear - age;// 传入的参数可以直接使用
    }
    
    void say(){// void的意思即为不返回任何参数
        System.out.println("我叫" + "name");
    }// 但是在void中可以使用return;意为将此方法结束
}

特别提示:当然你也可以直接在public类中定义方法,这些方法不需要实例化即可直接使用)

注意,想要使用这个类,还需要创建这个类的对象,即实例化。让我们回到public类当中,实现代码如下


public class ObjectOriented {

    public static void main(String[] args) {
        Person person = new Person();// 实例化该对象,命名为person
        // 之后只要与Person类相关,都需要使用person.xxx
        // 可以用此方法创建person1,person2....personN,他们互不干扰
        // 通过Person person2 = person;可以

        person.name = "小明";
        person.age = 8;
        person.height = 158;// 定义成员变量
        
        String name = person.getName();// 调用方法
        System.out.println(name);
        
        System.out.println(person.getBirthYear(2020));// 传入参数2020
        
        person.say();
    }

}



运行结果:
小明
2012
我叫小明

Process finished with exit code 0


类与对象的存储

在Java中,所有数据的存储都是自动的,即你不能手动更改各种数据被存储的位置。

Java中存储数据的位置被分为三块,栈内存,堆内存,和方法区。

其中方法区就是用来存储所有类的信息,以及其中的成员方法,静态的变量(static)和常量(final)也会被储存其中。

栈存储特点是先进后出,内存的区域一般比较小,但是栈的优点是存取速度很快,所以一般基本数据类型的数据和引用数据类型的引用会被存在栈中。

堆存储则是先进先出,内存的区域比较大,一般用于存放类的对象。

(这一部分内容虽然很难,看起来对编程似乎也没有帮助,但是理解之后能够对学习之后的内容很有帮助)

类与对象的更多操作

类的构造方法

构造方法,通常用于对象初始化,在对象被创建时,自动调用,所有类需要包含一个构造方法,构造方法的定义如下:
特别提示:如果没有自行编写一个构造方法,编译器会自动生成一个空的构造方法)


class Person{

    Person(){}
}

构造方法需要和类同名,可以传入参数,也可以在其中加入任何代码(就像一个自动执行的方法)


// 如果你这样定义构造方法
Person(String name){
    System.out.println(name);
}

// 则你在调用时需要
Person person = new Person("小明");

方法的重载

一个类中定义的方法是允许重载的,重载即不同的方法使用相同的方法名称。
但是重载也必须满足以下条件:

  • 方法名称相同
  • 参数列表的长度 参数列表类型 参数顺序不同
    特别提示:与返回值,和方法里面的语句无关)

// 在同一类Person中
    String getName(){
        return name;
    }

    String getName(String name){
        return name;
    }

    String getName(String firstName, String lastName){
        return firstName + lastName;
    }


// 可以通过如下方法依次调用
Person person = new Person();
String name = person.getName();
String name = person.getName("小明");
String name = person.getName("小", "明");


在调用重载的方法时,会根据参数传入的情况自动选择使用的方法。

构造方法也能进行重载

匿名的对象

所谓匿名的对象,即为创建对象时不命名该对象,让我们通过代码来说明


// 使用之前的getName方法
    String getName(){
        return name;
    }
 
 
 // 可以通过如下方式匿名调用getName方法
 new Person();// 匿名对象只会自动调用构造方法
 System.out.println(new Person().getName());// 直接输出
 String name = new Person.getName();// 新建一个变量用于存储
 

匿名调用的优点是节约内存空间,代码看起来也更整洁,缺点就是构建的对象只能使用一次,无法再进行调用。

练习使用

此部分内容比较多,对于初学者来说并不简单,通过小练习能帮助理解这一部分内容

请定义并测试一个代表员工的Employee类。它的属性包括“员工姓名”、 “员工号码”、“员工基本薪水”、“员工薪水增长率”;他的方法包括“构 造方法”、“获取员工姓名”、“获取员工号码”、“获取员工基本薪水”、 “计算薪水增长额”及“计算增长后的工资总额”。

答案代码如下(查看前至少先进行思考):


public class OOPBasic {
    public static void main(String[] args) {
        Employee employee = new Employee();
        employee.name = "大明";
        employee.idNumber = 6666;
        employee.salary = 10000;
        employee.salaryIncreaseRate = 0.01f;

        System.out.println(employee.getName());
        System.out.println(employee.getIdNumber());
        System.out.println(employee.getSalary());
        System.out.println(employee.calculateIncreaseAmount());
        System.out.println(employee.calculateSalary());
    }
}

class Employee{
    String name;
    int idNumber;
    float salary;
    float salaryIncreaseRate;

    Employee(){}

    String getName(){
        return name;
    }

    int getIdNumber(){
        return idNumber;
    }

    float getSalary(){
        return salary;
    }

    float calculateIncreaseAmount(){
        return salary * salaryIncreaseRate;
    }

    float calculateSalary(){
        return salary * (1 + salaryIncreaseRate);
    }
}


运行结果:
大明
6666
10000.0
100.0
10100.0

Process finished with exit code 0

关于类的使用的常见问题

在进行完练习之后,你可能会对类产生一些疑问,让我们在这里集中解答一下:

Q1:为什么我要使用类?看起来明显使整个程序变长了,变复杂了
在使用了类之后,整段代码的体量确实肉眼可见的变长了近一倍,但是注意我之前举的例子,小明在只开一家店的时候确实使用面向过程的思维更方便,但是当小明开连锁店的时候,事情就不一样了。
在这里也是一样,题中让你创建了一个员工大明,看起来使用类弊大于利,但是如果是一个数千人的企业,设想一下每个员工的name,id,salary都需要单独的声明,使用类则只需要创建对象,每个对象都能用.name,.id,.salary,能够使代码缩短很多。

Q2:类起到了什么作用?我输出的数据不都是我输入的吗?
通过上面的例子,你可能发现所有的数据输出都需要通过你自己的输入来产生。其实道理和Q1一样,在小体量代码时,用类不能帮助你降低代码量,但是当体量变大时,你计算员工薪资的涨幅都要用重复的代码堆砌,但是运用类,你只需要使用相同的方法。
注意一点,在真正的项目中,class中的内容会很多很复杂(数万行起),但是class的内容并不需要你自己编写,大部分时候你只需要调用别人class里的方法就好,本题中class的方法比较简单,只是想起到练习帮助理解的作用,但是本题中你也可以看出,你所编写的内容中不含任何的逻辑和运算,只是简单的创建对象-输入数据-输出数据(如果Person中的内容算作别人编写的)。

Q3:既然类是别人编写的,我为什么要学会定义类和类的结构?
学习类是为了更好的理解类,如果你完全不理解类的结构,就不能更好的使用类。
编写类就是面向对象语言的一种进阶,换言之,如果你能编写一个表意清晰,功能强大,能供多人使用的类,也说明了你的能力十分强大。

Q4:既然类在大体量时才作用明显,我能不能不学习类?
目前世界上绝大多数的大型项目都是由多人组成的团队编写的,如果你没有进一步学习的打算,不学习类也可以完成绝大多数简单的编程(包括对编程思维的培养),但是如果你想要真正深入的学习Java或者任何一门面向对象的语言,都需要透彻理解和接受类的存在。

转载请注明出处

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值