Java_面向对象编程-1

目录

主要内容

学习目标

第一节 类和对象

1.1. 面向过程和面向对象

1.2. 理解类和对象

第二节 类和对象

2.1. 定义类和创建对象

2.1.1. 属性(field 成员变量)

2.1.2. 方法

2.2. 局部变量

第三节 构造方法及其重载

3.1. 构造方法

3.2.  对象数组

第四节 方法调用

4.1.  基本数据类型的方法调用

4.2. 引用数据类型的方法调用

4.3.  this

4.3.1. 对象创建的过程和this的本质

4.3.2. this最常的用法:


主要内容

  1. 面向过程和面向对象
  2. 类和对象
  3. 成员变量和成员方法
  4. 局部变量
  5. 构造方法及其重载
  6. 方法调用
  7. this

学习目标

节数

知识点

要求

第一节(类和对象)

面向过程和面向对象

理解

类和对象

理解

第二节(类和对象)

成员变量

掌握

成员方法

掌握

局部变量

掌握

第三节(构造方法)

构造方法及其重载

掌握

对象数组

了解

第四节(方法调用)

方法调用-基本数据类型形参

掌握

方法调用-引用数据类型形参

掌握

this关键字

理解

第一节 类和对象

1.1. 面向过程和面向对象

        面向过程和面向对象都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。

        早期先有面向过程思想,随着软件规模的扩大,问题复杂性的提高,面向过程的弊端越来越明显的显示出来,出现了面向对象思想并成为目前主流的方式。两者都贯穿于软件分析、设计和开发各个阶段,对应面向对象就分别称为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)。C语言是一种典型的面向过程语言,Java是一种典型的面向对象语言。

示例1:开车和造车

        面向过程思想思考问题时,我们首先思考“怎么按步骤实现?”并将步骤对应成方法,一步一步,最终完成。 这个适合简单任务,不需要过多协作的情况下。比如,如何开车?我们很容易就列出实现步骤:

面向过程适合简单、不需要协作的事务,重点关注如何执行。

        但是当我们思考比较复杂的设计任务时,比如“如何造车?”,就会发现列出1234这样的步骤,是不可能的。那是因为,造车太复杂,需要很多协作才能完成。此时面向对象思想就应运而生了。

       面向对象(Oriented-Object)思想更契合人的思维模式。我们首先思考的是“怎么设计这个事物?” 比如思考造车,我们就会先思考“车怎么设计?”,而不是“怎么按步骤造车的问题”。这就是思维方式的转变。

比如,我们用面向对象思想思考“如何设计车”:

 天然的,我们就会从“车由什么组成”开始思考。发现,车由如下对象组成:

        为了便于协作,我们找轮胎厂完成制造轮胎的步骤,发动机厂完成制造发动机的步骤;这样,发现大家可以同时进行车的制造,最终进行组装,大大提高了效率。但是,具体到轮胎厂的一个流水线操作,仍然是有步骤的,还是离不开执行者、离不开面向过程思维!

       因此,面向对象可以帮助我们从宏观上把握、从整体上分析整个系统。 但是,具体到实现部分的微观操作(就是一个个方法),仍然需要面向过程的思路去处理。

       我们千万不要把面向过程和面向对象对立起来。他们是相辅相成的。面向对象离不开面向过程!

示例2:蛋炒饭和盖浇饭

        简单来说:用面向过程的方法写出来的程序是一份蛋炒饭,而用面向对象写出来的程序是一份盖浇饭。所谓盖浇饭,就是在米饭上面浇上一份盖菜,你喜欢什么菜,你就浇上什么菜。我觉得这个比喻还是比较贴切的。

 

        蛋炒饭肯定是把米饭和鸡蛋混在一起炒匀。盖浇饭呢,则是把米饭和盖菜分别做好,你如果要一份红烧肉盖饭呢,就给你浇一份红烧肉;如果要一份青椒土豆盖浇饭,就给浇一份青椒土豆丝。

        蛋炒饭的好处是入味均匀,吃起来香。如果恰巧你不爱吃鸡蛋,只爱吃青菜的话,那么唯一的办法就是全部倒掉,重新做一份青菜炒饭了。盖浇饭就没这么多麻烦,你只需要把上面的盖菜拨掉,更换一份盖菜就可以了。盖浇饭的缺点是入味不均,可能没有蛋炒饭那么香。

        到底是蛋炒饭好还是盖浇饭好呢?其实这类问题都很难回答,非要比个上下高低的话,就必须设定一个场景,否则只能说是各有所长。那么从饭馆角度来讲的话,做盖浇饭显然比蛋炒饭更有优势,他可以组合出来任意多的组合,而且不会浪费。

        盖浇饭的好处就是“菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用软件工程的专业术语就是“可维护性”比较好,“饭” 和“菜”的耦合度比较低。蛋炒饭将“蛋”“饭”搅和在一起,想换“蛋”“饭”中任何一种都很困难,耦合度很高,以至于“可维护性”比较差。软件工程追求的目标之一就是可维护性。面向对象的好处之一就是显著的改善了软件系统的可维护性。

·面向对象和面向过程思想的总结

  1. 都是解决问题的思维方式,都是代码组织的方式。
  2. 面向过程是一种“执行者思维”,解决简单问题可以使用面向过程。
  3. 面向对象是一种“设计者思维”,解决复杂、需要协作的问题可以使用面向对象。
  4. 面向对象离不开面向过程:
    1. 宏观上:通过面向对象进行整体设计
    2. 微观上:执行和处理数据,仍然是面向过程。。

面向过程

面向对象

区别

事物比较简单,可以用线性的思维去解决

事物比较复杂,使用简单的线性思维无法解决

共同点

面向过程和面向对象都是解决实际问题的一种思维方式

二者相辅相成,并不是对立的。

解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系、方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理

1.2. 理解类和对象

        我们人认识世界,其实就是面向对象的(此对象可不是男女谈对象的彼对象呀) 。比如现在让大家认识一下“天使”这个新事物,天使大家没见过吧,怎么样认识呢?最好的办法就是,给你们面前摆4个天使,带翅膀的美女,让大家看,看完以后,即使我不说,大家下一次是不是就都认识天使了。

        但是,看完10个天使后,我们总要总结一下,什么样的东东才算天使?天使是无数的,总有没见过的!所以必须总结抽象,便于认识未知事物!总结的过程就是抽象的过程。小时候,我们学自然数时怎么定义的?像1,2,3,4…这样的数就叫做自然数。 通过抽象,我们发现天使有这样一下特征:

  1. 带翅膀(带翅膀不一定是天使,还可能是鸟人)
  2. 女孩(天使掉下来脸着地,也是天使!)
  3. 善良
  4. 头上有光环

        那么通过这4个具体的天使,我们进行抽象,抽象出了天使的特征,我们也可以归纳一个天使类。 通过这个过程,类就是对象的抽象。

        类可以看做是一个模版,或者图纸,系统根据类的定义来造出对象。我们要造一个汽车,怎么样造?类就是这个图纸,规定了汽车的详细信息,然后根据图纸将汽车造出来。

        类:我们叫做class。 对象:我们叫做Object,instance(实例)。以后我们说某个类的对象,某个类的实例。是一样的意思。

示例1:英雄联盟、王者荣耀中的类和对象

        英雄就是类,具体的英雄,盖伦、提莫是对象。

 

示例2:月饼模具和月饼

        月饼模具是类,使用月饼模具制作的一个个月饼就是对象

总结

  1. 类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
  2. 类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

本节作业

  1. 理解面向过程和面向对象的异同
  2. 理解类和对象的关系

第二节 类和对象

2.1. 定义类和创建对象


        做了关于对象的很多介绍,终于进入代码编写阶段。本节中重点介绍类和对象的基本定义,属性和方法的基本使用方式。


2.1.1. 属性(field 成员变量)

        属性用于定义该类或该类对象包含的数据或者说静态特征。属性作用范围是整个类体。在定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化

数据类型

默认值

整型

0

浮点型

0.0

字符型

'\u0000'

布尔型

false

所有引用类型

null

属性定义格式:

[修饰符]  属性类型  属性名 = [默认值] ;

2.1.2. 方法

        方法用于定义该类或该类实例的行为特征和功能实现。方法是类和对象行为特征的抽象。方法很类似于面向过程中的函数。面向过程中,函数是最基本单位,整个程序由一个个函数调用组成。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。

方法定义格式:

[修饰符]  方法返回值类型  方法名(形参列表) {

   // n条语句

}

void代表没有返回值;方法的作用:重用代码,封装功能,便于修改

【示例1】定义类,模拟人的行为:吃饭工作和休息

  • 面向对象分析OOA

   从张三、李四、王五中提取出共同内容,提取一个类,人Person,包含共同的内容

   静态的特征:姓名、年龄、性别、住址

   动态的行为:eat、rest、work

  •  面向对象设计OOD  Design

    类:Person

    对象:zhangsan、lisi

    让对象完成功能 

  •  面向对象编程OOP  Programming
public class Person {
    //静态特征:成员变量  属性 field
    String name; //姓名
    int age;//年龄
    //动态的行为: 成员方法 method
    public void eat(){
        System.out.println("----人是铁饭是钢,一顿不吃饿得慌!!!-----");
    }
    public void work(){
        System.out.println(name+"-------在劳动------");
    }
    public void rest(String site){
        System.out.println(name+"在"+site+"休息");
    }
}

 【示例2】模拟实现具体人的特征和行为

public class Test {
    public static void main(String[] args) {
        //int n=5;
        int n;
        n = 5;
        System.out.println(n);
        Scanner input = new Scanner(System.in);
        //创建一个Person类的对象:张三并进行动态行为
        //Person person1 = new Person();
        Person person1; //方法中定义的变量,局部变量,没有默认值
        person1 = new Person();
        person1.name="zhangsan";
        person1.age = 23;
        person1.eat();
        person1.work();
        person1.rest("宿舍");
        //创建一个Person类的对象:李四并进行动态行为
        Person person2 = new Person();
        person2.name="lisi";
        person2.age=24;
        person2.work();
        person2.rest("工地");
        person2.eat();
    }
}

总结1:如何创建对象

    Scanner input = new Scanner(System.in);

    Person person1 = new Person();

    new 后面是构造方法,具体含义稍后讲解

总结2:如何操作属性:对象名.属性名

  person1.name="zhangsan";

  person1.age = 23;

总结3:如何调用方法: 对象名.方法名(实参列表)

   person1.eat();

   person1.work();

   person1.rest("宿舍");

 
总结4:内存分配图

 

2.2. 局部变量

        类中定义的变量是成员变量,而方法中定义的变量,包括方法的参数,代码块中定义的变量被称为局部变量。两个的区别主要表现在以下几方面:

成员变量

局部变量

代码中位置不同

类中定义的变量

方法或代码块中定义的变量

内存中位置不同

堆内存

栈内存

是否有默认值

没有

代码作用范围(空间)

当前类的方法

当前一个方法或代码块

作用时间不同

当前对象从创建到销毁

定义变量到所属方法或代码块执行完毕

 【示例3】使用计算器完成加法、减法运算

public class Calculator {
    //成员变量
    private String brand;//品牌
    private double size;//尺寸
    //成员方法
    public int add(int num1,int num2){
        int result;
        result = num1+num2;
        return result;
    }
    public int sub(int num1,int num2){
        return num1-num2;
    }
    public void show(){
        System.out.println("我购买了一个计算器"+brand+","+size);
    }
    public static void main(String[] args) {
        //购买运算器
        Calculator calc = new Calculator();
        calc.brand = "联想";
        calc.size = 6.5;
        calc.show();
        //使用运算器进行运算
        int num1 = 10;
        int num2 = 20;
        int result = calc.add(num1,num2);
        System.out.println(result);
        result = calc.sub(num1,num2);
        System.out.println(result);
    }
}
代码执行的内存分配图如下:

本节作业

  1. 定义Person类并创建多个Person对象,模拟人的行为
  2. 定义一个计算器类并模拟其行为

第三节 构造方法及其重载

3.1. 构造方法

        对于一个类来说,一般有三种常见的成员:属性field、方法method、构造器constructor。这三种成员都可以定义零个或多个。

        构造方法(constructor)也叫构造器,用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。构造器的名称应与类的名称一致。Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。

声明格式:

[修饰符] 类名(形参列表){

       //n条语句

}

构造器4个要点:

  1. 构造器的方法名必须和类名一致!
  2. 构造器通过new关键字调用!!
  3. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
  4. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义则编译器不会自动添加!

构造方法也是方法,只不过有特殊的作用而已。与普通方法一样,构造方法也可以重载。

【示例4】定义计算机类并模拟其操作

public class Computer {
    //成员变量
    private String cpu="Intel";//cpu
    private String memory;//内存
    private String mainBoard;//主板
    private String keyBoard;//键盘
    //构造方法
    public Computer(){
        System.out.println("--------Computer()--------");
        cpu = "AMD";
    }
    public Computer(String cpu,String memory,            
String mainBoard,String keyBoard){
        this.cpu = cpu;
        this.memory = memory;
        this.mainBoard = mainBoard;
        this.keyBoard = keyBoard;
    }
//    public Computer(String cpu1,String memory1,String mainBoard1,String keyBoard1){
//        cpu = cpu1;
//        memory = memory1;
//        mainBoard = mainBoard1;
//        keyBoard = keyBoard1;
//    }
    //成员方法
    public void start(){
        System.out.println("-------starting------");
    }
    public void close(){
        System.out.println("------- closing----------");
    }
    public void show(){
        System.out.println("cpu="+cpu+",memory="+memory+
",mainBoard="+mainBoard+",keyBoard"+keyBoard);
    }
    public static void main(String[] args) {
        //购买一台电脑
        Computer computer2 = new Computer();
//        computer.cpu="酷睿"; omputer.memory="三星";
//        computer.mainBoard="华硕"; computer.keyBoard="罗技";
        Computer computer = new Computer("酷睿","三星","华硕","罗技");
       //让电脑运行
        computer.start();
        computer.show();
        computer.close();
    }
}

新手雷区

 对象的创建完全是由构造方法实现的吗?

    不完全是。构造方法是创建Java对象重要途径,通过new关键字调用构造器时,构造器也确实返回了该类对象,但这个对象并不是完全由构造器负责创建的。创建一个对象分为如下四步:

1. 分配对象空间,并将对象成员变量初始化为0或空

2. 执行属性值的显示初始化

3. 执行构造方法

4. 返回对象的地址给相关的变量

新手雷区

    如果方法构造中形参名与属性名相同时,需要使用this关键字区分属性与形参。

         this.id 表示属性id;id表示形参id

3.2.  对象数组

已经学过数组了,但是数组元素都是基本数据类型或者String类型。学习了类和对象之后,可以定义数组的元素类型是更加复杂的引用引用数据类型,每个元素可以是一个具体的对象,称为对象数组。

【示例5】使用对象数组存储多台计算机信息

public class TestArray {
    public static void main(String[] args) {
        //定义一个数组,存储4个分数,并遍历
        int [] arr;
        arr = new int[4];
        arr[0] = 90;
        arr[1] = 80;
        arr[2] = 100;
        arr[3] = 54;
        for(int score : arr){    System.out.println(score);      }
        System.out.println("======================");
        //定义一个数组,存储4台计算机,并遍历
        //Computer [] arr2;
        //arr2 = new Computer[4];
        Computer [] arr2 = new Computer[4];
        arr2[0] = new Computer("酷睿","三星","华硕","罗技");
        arr2[1] = new Computer("Intel","金士顿","技嘉","双飞燕");
        arr2[2] = new Computer("AMD","三星","华硕","双飞燕");
        arr2[3] = new Computer("酷睿","金士顿","技嘉","罗技");
        for (Computer computer:arr2){
           // System.out.println(computer.toString());
            computer.show();
        }
    }
}

内存分配图入下图所示。

本节作业

  1. 定义一个“点”(Point)类用来表示二维空间中的点(有二个坐标)。要求如下:
    1. 可以生成具有特定坐标的点对象。
    2. 提供可以设置二个坐标的方法。
    3. 提供可以计算该“点”距另外点距离的方法。
  2. 使用对象数组存储多个对象并输出内容

第四节 方法调用

        方法调是Java开发中的基本操作。理解方法调用的内存分配过程,实参形参的传递过程非常必要。方法参数分为基本数据类型和引用数据类型两种,传递参数有着实质的区别。

4.1.  基本数据类型的方法调用

【示例6】基本数据类型的方法调用

public class TestPrimaryArgs {
    public static void main(String[] args) {
        //定义两个变量
        int num1 = 10;
        int num2 = 20;
        //输出交换前两个变量的值
        System.out.println("交换前:num1="+num1+",num2="+num2);
        //交换两个变量的值
        swap(num1,num2);
        //输出交换后两个变量的值
        System.out.println("交换后:num1="+num1+",num2="+num2);
    }
    public static void swap(int num1,int num2){
        int temp;
        temp = num1;
        num1 = num2;
        num2 = temp;
        System.out.println("交换后1:num1="+num1+",num2="+num2);
    }
}

4.2. 引用数据类型的方法调用

【示例7】引用数据类型的方法调用

public class Point {
    int x;
    int y;
}
public class TestRefArgs {
    public static void main(String[] args) {
        //定义两个变量
        Point p = new Point();
        p.x = 10;
        p.y = 20;
        //输出交换前两个变量的值
        System.out.println("交换前:p.x="+p.x+",p.y="+p.y);
        //交换两个变量的值
        swap(p);
        //输出交换后两个变量的值
        System.out.println("交换后:p.x="+p.x+",p.y="+p.y);
    }
    public static void swap(Point p){
        p = new Point();
        int temp;
        temp = p.x;
        p.x = p.y;
        p.y = temp;
    }
}

内存分配过程如图所示。

 新手雷区

        基本数据类型的参数是值传递,引用数据类型的参数传递是引用(地址),本质上也是值传递。

4.3.  this

4.3.1. 对象创建的过程和this的本质

        构造方法是创建Java对象的重要途径,通过new关键字调用构造器时,构造器也确实返回该类的对象,但这个对象并不是完全由构造器负责创建。创建一个对象分为如下四步:

1. 分配对象空间,并将对象成员变量初始化为0或空

2. 执行属性值的显示初始化

3. 执行构造方法

4. 返回对象的地址给相关的变量

       this的本质就是“创建好的对象的地址”!  由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。

4.3.2. this最常的用法:

  1. 调用成员变量:如果成员变量和局部变量同名,this必须书写,用来区分两者;如果没有同名的局部变量,this可以不写
  2. 调用成员方法:这种情况下,this可以省略
  3. 调用构造方法:使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
  4. this不能用于static方法中。

【示例8】this关键字的使用

public class Student {
    //成员变量
    private int sno;//学号
    private String name;//姓名
    private String sex;//性别
    private double score;//分数
    //构造方法
    public Student(){
    }
    public Student(int sno,String name,String sex ){
        this.sno = sno;
        this.name = name;
        this.sex = sex;
    }
    public Student(int sno,String name,String sex ,double score){
        this(sno,name,sex);
        //new Student(sno,name,sex);
//        this.sno = sno;
//        this.name = name;
//        this.sex = sex;
        this.score = score;
    }
    //成员方法
    public void study(){
        this.shout();
        shout();
        //System.out.println("好好学习,天天向上。add oil!!!");
        System.out.println("在教室努力的学习中,代码量一行行提升了.....");
    }
    public void shout(){
        System.out.println("好好学习,天天向上。add oil!!!");
    }
    public void show(){
        System.out.println(sno +"   "+this.name+"  "+sex+"  "+this.score);
    }
    public static void main(String[] args) {
        Student stu = new Student(7,"田七","男",77);
        stu.study();
        stu.shout();
        stu.show();
        //study();
        Student stu2 = new Student();
    }
}

本节作业

  1. 练习基本数据类型的参数传递
  2. 练习引用数据类型的参数传递
  3. this关键字的作用和用法
  4. 练习this关键字的使用

猜你喜欢

转载自blog.csdn.net/weixin_45859844/article/details/120433176
今日推荐