A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 xiekai_sjz 于 2018-9-7 15:56 编辑

day06 类与对象 封装 构造方法
    面向对象是Java语言的核心,是程序设计的思想。今天我们就进入面向对象的学习。
    以下是今天的学习目标:
  • 能够理解面向对象的思想
  • 能够明确类与对象关系
  • 能够掌握类的定义格式
  • 能够掌握创建对象格式,并访问类中的成员
  • 能够完成手机类的练习
  • 能够理解对象的内存图
  • 能够说出成员变量和局部变量的区别
  • 能够理解private关键字的含义
  • 能够说出this关键字可以解决的问题
  • 能够理解构造方法的含义
  • 能够用封装的思想定义一个标准类


    以下是今天的详细笔记:

面向对象思想&类的定义和使用
面向对象思想的概述
面向过程: 实现一个功能, 要自己亲力亲为, 一步一步的完成
面向对象: 实现一个功能, 不用关心具体步骤, 而是找到合适的对象, 来帮你做这件事
面向对象思想的举例
面向过程: 强调做事的步骤
面向对象: 强调做事的对象

面向对象思想的特点:
        更符合思考习惯
        将复杂的事情简单化
        将我们从执行者变成了指挥者

面向对象的三大基本特征
        1. 封装
        2. 继承
        3. 多态
类和对象的关系
类: 是一组相关属性和行为的集合
        属性: 描述事物的状态信息
        行为: 事物能做什么

对象: 一类事物的具体体现

类与对象的关系: 类是对象的模板, 对象是类的实体
        类是对一类事物的描述, 是抽象的
        对象是一类事物的实例, 是具体的

事物和类的相互转换及类的定义
、事物和类的转换:
        事物: 类
        事物的属性: 类的成员变量
        事物的行为: 类的成员方法

成员变量: 定义在类中方法外面的变量
成员方法: 定义在类中的方法, 没有static

类的定义格式:

    public class 类名 {
        // 成员变量
        // 成员方法
    }

补充:
[Java] 纯文本查看 复制代码
// 示例: 学生类
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 类名();

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

使用对象的成员方法:
        对象名.成员方法名()

main()方法要写在测试类中
补充:
[Java] 纯文本查看 复制代码
// 测试类
public class Demo02Student {

    public static void main(String[] args) {
        // 创建对象: 类名 对象名 = new 类名();
        Student stu = new Student();  // 创建一个对象, 对象的成员变量有默认值

        // 使用对象的成员变量: 对象名.成员变量名
        System.out.println(stu.name);   // null
        System.out.println(stu.age);    // 0

        // 修改对象的成员变量值
        stu.name = "赵丽颖";
        stu.age = 18;
        
        // 获取对象的成员变量值
        System.out.println(stu.name);   // 赵丽颖
        System.out.println(stu.age);    // 18

        // 使用对象的成员方法: 对象名.成员方法名()
        stu.eat();
        stu.sleep();
        stu.study();
    }
}

手机类练习
[Java] 纯文本查看 复制代码
public class Phone {

    // 成员变量
    String brand; // 品牌
    double price; // 价格
    String color; // 颜色

    // 成员方法
    public void call(String who) {
        System.out.println("给" + who + "打电话");
    }

    public void sendMessage() {
        System.out.println("群发短信");
    }
}

public class Demo01PhoneOne {

    public static void main(String[] args) {
        // 根据Phone类,创建一个名为one的对象
        // 格式:类名称 对象名 = new 类名称();
        Phone one = new Phone();
        System.out.println(one.brand); // null
        System.out.println(one.price); // 0.0
        System.out.println(one.color); // null
        System.out.println("=========");

        one.brand = "苹果";
        one.price = 8388.0;
        one.color = "黑色";
        System.out.println(one.brand); // 苹果
        System.out.println(one.price); // 8388.0
        System.out.println(one.color); // 黑色
        System.out.println("=========");

        one.call("乔布斯"); // 给乔布斯打电话
        one.sendMessage(); // 群发短信
    }

}

5分钟练习: 定义手机类创建对象并测试需求:
定义手机类, 属性有品牌(brand), 价格(price), 颜色(color), 行为有给XXX打电话, 群发短息
定义测试类, 在测试类中创建手机对象, 为手机属性赋值, 调用手机的方法
代码:
[Java] 纯文本查看 复制代码
/*
定义手机类, 属性有品牌(brand), 价格(price), 颜色(color), 行为有给XXX打电话, 群发短息
 */
public class Phone {
    // 属性 (成员变量)
    String brand;
    double price;
    String color;

    // 行为 (成员方法)
    // 给某人打电话
    public void call(String who) {
        System.out.println("给" + who + "打电话");
    }

    // 群发短信
    public void sendMessage() {
        System.out.println("群发短信");
    }
}

/*
需求:
定义手机类, 属性有品牌(brand), 价格(price), 颜色(color), 行为有给XXX打电话, 群发短息
定义测试类, 在测试类中创建手机对象, 为手机属性赋值, 调用手机的方法
 */
public class Test {
    public static void main(String[] args) {
        // 创建手机类对象  类名 对象名 = new 类名();
        Phone p = new Phone();

        // 获取手机对象的成员变量默认值并打印
        System.out.println(p.brand);
        System.out.println(p.price);
        System.out.println(p.color);

        // 修改手机对象的成员变量值
        p.brand = "小米";
        p.price = 9999.0;
        p.color = "黑色";

        // 再次获取手机对象的成员变量默认值并打印
        System.out.println(p.brand);
        System.out.println(p.price);
        System.out.println(p.color);

        // 调用对象的成员方法
        p.call("雷军");
        p.sendMessage();
    }
}


创建对象内存图&类名的使用一个对象的内存图细节:
        对象在堆内存中
        每个对象都有各自的一份成员变量
        对象的成员方法通过对象保存的地址值指向方法区中
        方法调用时会进栈.(压栈), 执行完毕后会出栈(弹栈), 释放内存空间

两个对象使用同一个方法的内存图
细节:
        new出来的多个对象, 每个对象都有单独的内存区域
        每个对象保存各自的成员变量
        多个对象共用方法区中的成员方法
两个引用指向同一个对象的内存图细节:
        两个引用指向同一个对象, 虽然引用变量不同, 但保存的是同一个地址值, 实际就是使用同一个对象

补充:
[Java] 纯文本查看 复制代码
// 两个引用指向同一个对象
Phone one = new Phone();
Phone two = one;

使用对象类型作为方法的参数
知识点:
我们自己定义的类的对象, 能否作为方法的参数, 如何定义参数列表, 如何传参?
传递一个对象时, 实际传递的是什么?
[Java] 纯文本查看 复制代码
// 定义方法打印一个字符串
public static void print(String s) {
    System.out.println(s);
}
// 调用方法
print("hello");

// 定义方法打印一个手机Phone对象
publc static void print(Phone p) { 
    System.out.println(p);
}
// 调用方法
Phone p = new Phone();
print(p);

总结:
引用数据类型作为参数, 实际传递的是对象的地址值
补充:
[Java] 纯文本查看 复制代码
public class Demo04PhoneParam {

    public static void main(String[] args) {
        Phone one = new Phone();
        one.brand = "苹果";
        one.price = 8388.0;
        one.color = "土豪金";

        method(one);     // 传递进去的参数其实就是地址值
    }

    public static void method(Phone param) {
        System.out.println(param.brand); // 苹果
        System.out.println(param.price); // 8388.0
        System.out.println(param.color); // 土豪金
    }
}

使用对象类型作为方法的返回值知识点:
我们自己定义的类的对象, 能否作为方法的返回值, 如何定义返回值类型, 如何return?
返回一个对象时, 实际返回的是什么?
[Java] 纯文本查看 复制代码
// 定义方法获取一个字符串
public static String getString() {
    return "hello";
}
// 调用方法
String s = getString();

// 定义方法获取一个手机Phone对象
publc static Phone getPhone() {
    Phone p = new Phone();
    return p;
}
// 调用方法
Phone p = getPhone();

总结:
引用数据类型作为返回值, 实际返回的是对象的地址值
补充:
[Java] 纯文本查看 复制代码
public class Demo05PhoneReturn {

    public static void main(String[] args) {
        Phone two = getPhone();
        System.out.println(two.brand); // 苹果
        System.out.println(two.price); // 8388.0
        System.out.println(two.color); // 玫瑰金
    }

    public static Phone getPhone() {
        Phone one = new Phone();
        one.brand = "苹果";
        one.price = 8388.0;
        one.color = "玫瑰金";
        return one;
    }
}

成员变量和局部变量的区别成员变量和局部变量的区别:
    1. 在类中的位置不同
       成员变量:类中,方法外
       局部变量:方法中或者方法声明上 (形式参数)
    2. 作用范围不一样
       局部变量:方法中
       成员变量:类中
    3. 初始化值的不同
       局部变量:没有默认值。必须先定义,赋值,最后使用
       成员变量:有默认值
    4. 在内存中的位置不同
       局部变量:栈内存
       成员变量:堆内存
    5. 生命周期不同
       局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
       成员变量:随着对象的创建而存在,随着对象的消失而消失
封装&this&构造方法面向对象三大特征之封装性面向对象三大特征:
    1. 封装
    2. 继承
    3. 多态

封装: 就是将不需要让外界知道的细节信息隐藏起来

封装的原因: 为了实现代码的解耦

封装的体现:
        定义方法将复杂的逻辑封装, 使用时只需要知道方法名
        使用 private 关键字将成员变量隐藏起来
private关键字的作用及使用
private: 是一种权限修饰符. 可以修饰类, 成员变量, 成员方法. 被其修饰的成员只能在其所在类中访问.

成员变量的封装原则:
        使用private修饰
        提供public修饰的 setXxx() 和 getXxx() 方法
补充:
[Java] 纯文本查看 复制代码
public class Person {
    // 使用private修饰成员变量
    private String name;
    private int age;
    
    // 提供public的setXxx(), getXxx()方法
    // 修改name属性值
    public void setName(String n) {
        name = n;
    }
    
    // 获取name属性值
    public String getName() {
        return name;
    }
    
    // 修改age属性值
    public void setAge(int a) {
        age = a;
    }
    
    // 获取age属性值
    public int getAge() {
        return age;
    }
}

// 测试类
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        // 修改属性值
        p.setAge(10);
        // 获取属性值
        int a = p.getAge();
    }
}
练习使用private关键字定义学生类5分钟练习: private定义学生类需求:
定义学生(Student)类, 属性姓名(name), 年龄(age), 是否男士(male), 将属性私有, 提供set/get方法
定义测试类, 创建学生对象, 通过setXxx方法为属性赋值, 通过getXxx方法获取属性值
代码::
[Java] 纯文本查看 复制代码
/*
定义学生(Student)类, 属性姓名(name), 年龄(age), 是否男士(male), 将属性私有, 提供set/get方法
 */
public class Student {

    // 成员变量
    private String name;   // 姓名
    private int age;       // 年龄
    private boolean male;  // 是否男士

    // 提供对应的get/set方法
    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

    public void setAge(int a) {
        age = a;
    }

    public int getAge() {
        return age;
    }

    public void setMale(boolean m) {
        male = m;
    }

    public boolean isMale() {
        return male;
    }
}

/*
需求:
定义学生(Student)类, 属性姓名(name), 年龄(age), 是否男士(male), 将属性私有, 提供set/get方法
定义测试类, 创建学生对象, 通过setXxx方法为属性赋值, 通过getXxx方法获取属性值
 */
public class Test {
    public static void main(String[] args) {
        // 创建学生对象
        Student s = new Student();

        // 设置属性
        s.setName("王大锤");
        s.setAge(30);
        s.setMale(true);

        // 获取属性值并打印
        System.out.println(s.getName());
        System.out.println(s.getAge());
        System.out.println(s.isMale());
    }
}

补充:
set/get 方法常见规则:
boolean 类型的属性, 对应方法名为 isXxx() 和 setXxx()
        例如 male 属性:
                public boolean isMale(){}
                public void setMale(boolean m)
其他数据类型仍然是 setXxx() 和 getXxx()
this关键字的作用
知识点:
当局部变量和成员变量重名时, 方法中使用一个变量, 使用的是哪个
如何区分局部变量和成员变量
this代表什么, 有什么用处

[Java] 纯文本查看 复制代码
public class Person {
    private String name;                  // 成员变量
    
    public void sayHello(String name) {   // 局部变量
        System.out.println(name + ",你好。我是" + name);  // name是哪个?
    }
}

总结:
使用变量时的就近原则:
        如果有局部变量, 则是局部变量
        如果没有局部变量, 有成员变量, 则是成员变量
        如果没有局部变量, 也没有成员变量, 则报错

this: 代表所在类的对象的引用.
        注意: 只能在方法中使用, 哪个对象调用该方法, this就代表哪个对象

this的作用:
        解决局部变量和成员变量重名的问题
        可以通过this.成员变量名直接访问成员变量
补充:
[Java] 纯文本查看 复制代码
public class Person {
    private String name;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public void sayHello(String name) {
        System.out.println(name + ",你好。我是" + this.name);
    }
}
构造方法构造方法: 在创建对象时使用new关键字调用, 用于为对象进行初始化

定义格式:
        方法名和类名一致; 没有返回值类型
        
    public 类名(参数类型 参数名, ...) {
        // 初始化代码
    }

构造方法的注意事项:
        1. 方法名和类名完全一样
        2. 没有返回值类型, 连void都不写
        3. 不能return一个具体的返回值
        4. 一个类如果没有定义任何的构造方法, 那么编译器会提供一个默认的无参构造方法
        5. 一个类如果定义了有参构造, 而没有定义无参构造, 那么编译器不会提供默认的无参构造. 如需使用无参构造则需要自己手动定义
        6. 构造方法也可以重载, 有参和无参构造就是重载关系
补充:
[Java] 纯文本查看 复制代码
// 示例
public class Person {
    private String name;
    
    // 无参构造
    public Person() {
        
    }
    
    // 有参构造
    public Person(String name) {
        this.name = name;
    }
    
    // ...
}

定义一个标准的类
JavaBean: 用于存储和描述数据的类

标准JavaBean的定义格式:
        1. private修饰成员变量
        2. 无参, 有参构造
        3. public的get/set方法

    // 标准JavaBean的类的结构
    public class 类名 {
        // 成员变量
        // 无参构造
        // 有参构造
        // set/get方法
        // 其他成员方法
    }

IDEA自动生成代码:
        生成构造: Alt + Insert -> Constructor
        生成get/set方法: Alt + Insert -> Getter and Setter
补充:
[Java] 纯文本查看 复制代码
// 标准学生类
public class Student {
        // 私有成员变量
    private String name; 
    private int age; 

        // 构造方法
    public Student() {}

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

        // get/set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        }
}

5分钟练习: 定义标准学生类
需求: 定义学生类, 属性姓名(name), 年龄(age), 私有修饰, 并提供set/get方法, 提供无参, 有参构造方法
定义测试类, 在测试类中创建学生对象
代码:
[Java] 纯文本查看 复制代码
/*
需求: 定义学生类, 属性姓名(name), 年龄(age), 私有修饰, 并提供set/get方法, 提供无参, 有参构造方法
 */
public class Student {

    // 成员变量
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

/*
需求: 定义学生类, 属性姓名(name), 年龄(age), 私有修饰, 并提供set/get方法, 提供无参, 有参构造方法
定义测试类, 在测试类中创建学生对象
 */
public class Test {
    public static void main(String[] args) {
        // 创建对象
        Student s1 = new Student();
        s1.setName("王大锤");
        s1.setAge(30);
        System.out.println(s1.getName());
        System.out.println(s1.getAge());

        System.out.println("=============");

        // 使用有参构造创建对象
        Student s2 = new Student("小美", 20);
        System.out.println(s2.getName());
        System.out.println(s2.getAge());

    }
}





















7 个回复

倒序浏览
消灭零回复
回复 使用道具 举报
臭蛋 来自手机 初级黑马 2018-8-29 18:18:22
藤椅
听完课有点蒙,不过再看一遍笔记思路就清晰了许多..............地表最帅的一座铁岭
回复 使用道具 举报
臭蛋 发表于 2018-8-29 18:18
听完课有点蒙,不过再看一遍笔记思路就清晰了许多..............地表最帅的一座铁岭 ...

勤加练习
回复 使用道具 举报
dachou1996 来自手机 初级黑马 2018-8-29 18:40:43
报纸
xiekai_sjz 发表于 2018-8-29 18:32
勤加练习

老师…我是铁岭,上面是袁子涵回的你……他在皮
回复 使用道具 举报
H!灬 来自手机 初级黑马 2018-8-30 07:30:02
地板
回复 使用道具 举报
臭蛋 初级黑马 2018-8-31 17:13:05
7#
dachou1996 发表于 2018-8-29 18:40
老师…我是铁岭,上面是袁子涵回的你……他在皮

                                          你更皮
回复 使用道具 举报
Bin@ 中级黑马 2019-4-17 08:42:49
8#
66666666666666666666666666666
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马