本帖最后由 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());
}
}
|
|