JavaSE-06 [面向对象+封装]
第一章 面向对象思想
1.1 面向过程和面向对象
- 面向过程: 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
- 面向对象: 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
- 总结 
  - 都是解决问题的思维方式,都是代码的组织方式
- 解决简单问题可以使用面向过程
- 解决复杂问题,宏观上使用面向对象把握,微观处理上仍然使用面向过程处理
 
面向对象编程的三大特征(抽象)
- 封装:需要让用户知道的暴露出来,不需要用户知道的隐藏起来,这就是封装–“该露的露,该藏的藏”
- 继承:一方面,继承的本质是对某一批类的抽象,从而实现对现实世界更好的封装。另一方面,代码的重用
- 多态:为了提高处理问题的灵活性,原始的抽象的事务,可以出现多种不同的形态展现
1.2 类和对象
什么是类
- 类: 类是一组相关属性和行为的集合,可以看成是一类事物的模板,使用事务特征和行为特征来描述该类事物
- 显示中,描述一类事物 
  - 属性:就是事物的状态信息
- 行为:就是事物的功能
 
什么是对象
- 对象:对象是一类事物的具体体现,对象是类的一个实例,必然具备该事物的属性和行为
- 现实中。一类事物的一个实例,就是一个对象
类和对象的关系
- 关系: 
  - 类可以看做是一个模板,或者图纸,系统根据类的定义来创造出对象
- 类是对一类事物的描述,是抽象的
- 对象是一类事物的实例,是具体的
 
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16dYKIgT-1686187958338)(photo/JavaSE06_面向对象之封装.assest/1664605398568.png)]
1.3 类的定义
事物与类的对比
- 显示世界的一类事物 
  - 属性:事物的状态信息
- 行为:事物的功能和作用
 
- Java中用class描述事物也是如此 
  - 成员变量:对应事物的属性
- 成员方法:对应事物的行为
 
类的定义格式
public class 类的名称{
    //成员变量
    //成员方法
}
- 定义类:就是定义类的成员,包括成员属性和成员方法
- 成员变量:定义在类中,方法外
- 成员方法:定义在类中,与之前的方法不一致的是,去掉了static
/**
 * 类的定义
 *  定义一个类,用于模拟学生事物,由两部分组成
 *      学生属性:年龄。升高。体重...
 *      学生行为:学习、运动、睡觉...
 *  对应在Java中:
 *      成员变量:数据类型 变量名;
 *      成员方法:修饰符 返回值类型 方法名(){}
 *  注意事项:
 *      成员变量在类中,方法外
 *      成员方法不需要写static关键字
 */
public class Student{
    //成员变量
    String name; //姓名
    int age;//年龄
    String address;//地址
    //成员方法
    public void study(){
        System.out.println("好好学习");
    }
    public void paly() {
        System.out.println("多运动多锻炼");
    }
    public void sleep(){
        System.out.println("中午午休");
    }
}
1.4 对象的使用
对象的使用格式
- 一般情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用
- 创建对象的步骤: 
  - 1、导包:指出使用的类存放的位置,如果在同包中,导包省略
- 2、创建:类名称 对象名 = new 类名称();
- 3、使用:两种情况 
    - 使用成员变量:对象名.成员变量;
- 使用成员方法:对象名.成员方法();
 
 
- 注意事项 
  - 如果成员变量没有赋值,那么就会出现默认值
- 整数类型的默认值是0,引用数据类型的默认值是null
 
**
 * 对象的使用:
 *  一般情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用
 * 创建对象步骤:
 *  1、导包:指出使用的类存放的位置,如果在同包中,导包省略
 *  2、创建:类名称 对象名 = new 类名称();
 *  3、使用:两种情况
 *      使用成员变量:对象名.成员变量;
 *      使用成员方法:对象名.成员方法();
 *  注意事项:如果成员变量没有赋值,那么就会出现默认值,
 *          整数类型的默认值是0,引用数据类型的默认值是null
 */
public class StudentTest {
    public static void main(String[] args) {
        //1、导包:和测试类在同包,可以省略
        //2、创建对象:类名称 对象名 = new 类名称();
        Student stu1 = new Student();
        //3、使用:
        //使用成员变量: 对象名.成员变量;
        System.out.println(stu1.name);//numm
        System.out.println(stu1.age);//0
        System.out.println(stu1.address);//null
        System.out.println("------------------------");
        //改变对象中的成员变量的属性值
        stu1.name="Tom";
        stu1.age=33;
        stu1.address="北京";
        System.out.println(stu1.name);//Tom
        System.out.println(stu1.age);//33
        System.out.println(stu1.address);//北京
        //使用成员方法: 对象名.成员方法();
        stu1.study();
        stu1.paly();
        stu1.sleep();
    }
}
成员变量的默认值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5WBNSHPs-1686187958342)(photo/JavaSE06_面向对象之封装.assest/1664606932784.png)]
1.5 类与对象的练习
- 定义一个类,用来模拟”电脑“事物
/**
 * 类和对象的练习
 */
public class ComputerTest {
    public static void main(String[] args) {
        //创建对象格式:类名称 对象名称 = new 类名称();
        Computer computer = new Computer();
        //输出成员变量的默认值
        System.out.println(computer.brand);//null
        System.out.println(computer.price);//0.0
        System.out.println(computer.color);//null
        //修改成员变量的属性值
        computer.brand = "华为";
        computer.price = 5000.0;
        computer.color = "pink";
        System.out.println(computer.brand);
        System.out.println(computer.price);
        System.out.println(computer.color);
        //调用成员方法: 对象名称.方法名();
        computer.playGame();
        computer.lookMovie();
        computer.chart();
    }
}
1.6 对象内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIm2zNzs-1686187958346)(photo/JavaSE06_面向对象之封装.assest/1664705217813.png)]
-  1、单个对象内存图 - 成员变量
  - 成员方法
  
-  2、多个对象内存图 - 内存指向
  - 成员变量
  - 成员方法
  
-  总结: - 先加载Computer类信息`:属性与方法
- 进行默认初始化,再显示初始化(double price = 5000.0)最后执行构造方法初始化`
- 把堆中的地址赋给computer,computer就指向对象,computer是对象的引用`,或者叫对象名
- 当执行到方法时,就会开辟独立的空间(栈)`
- 方法执行完毕/执行到return就会返回到调用方法的地方`
- 继续执行后续代码
- 当main方法(栈)`执行完毕,程序退出
 
使用对象类型作为方法的参数
/**
 * 类和对象的关系
 *  使用对象类型作为方法额参数
 */
public class ComputerTest2 {
    public static void main(String[] args) {
        Computer c1 = new Computer();
        c1.brand = "苹果";
        c1.price = 10000.0;
        getFieldsFromC1(c1);
    }
    private static void getFieldsFromC1(Computer c1) {
        System.out.println(c1.brand);//苹果
        System.out.println(c1.price);//10000.0
    }
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7LkYR0uk-1686187958383)(photo/JavaSE06_面向对象之封装.assest/1664710589356.png)]
使用对象类型作为方法的返回值
/**
 * 类和对象的关系---内存图
 *  使用对象类型作为方法的返回值
 */
public class ComputerTest3 {
    public static void main(String[] args) {
        Computer c2 = getComputer();
        System.out.println(c2.brand);//戴尔
        System.out.println(c2.price);//6000.0
    }
    private static Computer getComputer() {
        Computer c3 = new Computer();
        c3.brand = "戴尔";
        c3.price = 6000.0;
        return c3;
    }
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YwfzzYcZ-1686187958384)(photo/JavaSE06_面向对象之封装.assest/1664710456591.png)]
1.7 成员变量和局部变量
- 局部变量和成员变量的区别
- 1、定义的位置不一样 
  - 局部变量:定义在方法的内部
- 成员变量:定义在类的内部,方法的外部
 
- 2、作用域不一样 
  - 局部变量:只有在方法中才能使用,出了方法不能使用
- 成员变量:在整个类中通用
 
- 3、默认值不一样 
  - 局部变量:没有默认值,必须手动赋值
- 成员变量:默认会有初始值
 
- 4、内存的位置不一样 
  - 局部变量:存储在栈内存
- 成员变量:存储在堆内存
 
- 5、生命周期不一样 
  - 局部变量:随着方法的进栈而诞生,随着方法的出栈而消失
- 成员变量:随着对象被创建而诞生,随着对象被垃圾回收器回收被销毁
 
/**
 * 局部变量和成员变量的区别
 *  1、定义的位置不一样
 *      局部变量:定义在方法的内部
 *      成员变量:定义在类的内部,方法的外部
 *  2、作用域不一样
 *      局部变量:只有在方法中才能使用,出了方法不能使用
 *      成员变量:在整个类中通用
 *  3、默认值不一样
 *      局部变量:没有默认值,必须手动赋值
 *      成员变量:默认会有初始值
 *  4、内存的位置不一样
 *      局部变量:存储在栈内存
 *      成员变量:存储在堆内存
 *  5、生命周期不一样:
 *      局部变量:随着方法的进栈而诞生,随着方法的出栈而消失
 *      成员变量:随着对象被创建而诞生,随着对象被垃圾回收器回收被销毁
 */
public class VariableDemo01 {
    //成员变量
    String username;
    //成员方法
    public void sleep(){
        //局部变量
        int num;//局部变量没有默认值,要使用,需需要手动赋值
        //System.out.println(num);//Variable 'num' might not have been initialized
        //作用域:局部变量只在方法中可以使用
        int num1 = 20;
        System.out.println(num1);
        //成员变量在整个类中可以被使用
        System.out.println(username);//成员变量存在默认值 null
    }
    //成员方法传参(参数属于方法的一部分,是局部变量)
    public void eat(int num2){
        //此时输出变量num2不报错
        //原因是,方法被定义之后,需要调用才能被执行
        //在调用时必须要传参数值,也就是变量接收到数据值,属于手动赋值
        //所以编译不报错
        System.out.println(num2);
    }
}
第二章 封装
2.1 封装的定义
- 封装的定义
封装就是把属于同一类事物的共性放到一个类中,
将不需要对外提供的内容都隐藏起来、
把属性都隐藏,提供公共方法对其访问。
- 封装的好处
将变化隔离、便于使用、提高重用性、提高安全性
- 封装的原则
将不需要对外提供的内容都隐藏起来、
把属性都隐藏,提供公共方法对其访问
2.2 private关键字
private关键字:
	1、private是用于对需要保护的成员变量进行修饰。
	2、一旦使用private关键字,在本类当中仍可以随意访问,
	   但是在本类之外就不能访问。
	3、如果想访问private关键字修饰的成员变量,
	   就需要定义一对setter/和getter方法
注意事项:
- 方法名:必须使用setXxx或者getXxx命名规则
- 对于getter来说,不能有参数,返回值类型和成员变量对应
- 对于setter来说,不能有返回值,参数类型和成员变量对应
- 对于基本数据类型的boolean型,setter方法同上,
  但是获取的方法是使用isXxx()
public class Person {
    String name;//姓名
    private int age;//年龄
    public void info(){
        System.out.println(name+":"+age);
    }
    //此方法专门用于向age设置值
    public void setAge(int age) {
        if (0<=age && age>=100 ){
            this.age = age;
        }else {
            System.out.println("输入的年龄错误");
        }
    }
    //此方法专门获取age的值
    public int getAge() {
        return age;
    }
}
/**
 * private关键字的使用
 */
public class Demo01_Private {
    public static void main(String[] args) {
        Person p = new Person();
        p.name = "张曼玉";
        //p.age = 22; 被private关键字修饰的成员变量不能在其他类直接访问
        //System.out.println(p.age);
        //基于逻辑的合理性,可以在setAge()方法中进行对参数判断
        p.setAge(-22);
        System.out.println(p.getAge());
    }
2.3 this关键字
- this关键字的使用
- 1、当方法的局部变量和类的成员变量名称相同时,
	 就遵循就近原则,优先使用局部变量
- 2、如果必须使用成员变量,则需要使用this关键字,
	 即:this.成员变量
- 3、this关键字:指向调用方法的对象,
	 即通过谁调用的方法,this就是谁
public class Student {
    String name;
    //成员变量的名称与局部变量的名称没有重名
    public void sayName1(String str){
        System.out.println(name +"---"+str);
    }
    //成员变量的名称和局部变量的名称一致
    //当方法的局部变量和类的成员变量名称相同时,跟进就近原则,优先使用局部变量
    public void sayName2(String name){
        System.out.println(name+"==="+name);
    }
    //成员变量和局部变量名称一致时,如果必须使用成员变量,则需要使用this关键字,即:this.成员变量
    public void sayName3(String name){
        System.out.println(this.name+"+++"+name);
        //验证this的身份
        System.out.println(this);
    }
}
/**
 * this关键字的使用
 *  1、当方法的局部变量和类的成员变量名称相同时,就遵循就近原则,优先使用局部变量
 *  2、如果必须使用成员变量,则需要使用this关键字,即:this.成员变量
 *  3、this关键字:指向调用方法的对象,即通过谁调用的方法,this就是谁
 */
public class Demo01_This {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.name = "巩俐";
        //成员变量的名称与局部变量的名称没有重名
        s1.sayName1("章子怡");
        //成员变量的名称和局部变量的名称一致
        //当方法的局部变量和类的成员变量名称相同时,就遵循就近原则,优先使用局部变量
        s1.sayName2("关之琳");
        //成员变量和局部变量名称一致时,如果必须使用成员变量,则需要使用this关键字,即:this.成员变量
        s1.sayName3("邱淑贞");
        //验证this是否是当前调用者--即当前对象
        System.out.println(s1);//打印对象地址值
    }
}

2.4 构造方法
- 1、构造方法作用
1、是用来专门创建对象的方法
2、当我们通过关键字new来创建对象时,
   其实就是在调用构造方法
- 2、构造方法格式:
//无参构造
public 类名称(){
      
}
//有参构造
public 类名称(参数类型 参数名,参数类型 参数名){
    方法体;
}
- 3、注意事项:
1、构造方法的名称必须和类的名称一致,包含大小写一致
2、构造方法不需要写返回值类型,包括void
3、构造方法没有返回值
4、如果没有声明任何构造方法,
   编译器会默认提供一个无参数的构造方法供使用
5、一旦编写任意构造方法,编译器将不提供无参构造方法
6、如果已经创建有参构造,那么无参构造默认不存在,
   需要手动定义无参构造
public class User {
    //成员变量
    private String name;
    private int age;
    //无参构造
    public User() {
        System.out.println("无参构造方法执行了");
    }
    //全参构造
    public User(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造方法执行了");
    }
    //获取属性值
    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;
    }
}
/**
 * 构造方法:
 *      1、是用来专门创建对象的方法
 *      2、当我们通过关键字new来创建对象时,其实就是在调用构造方法
 *  构造方法格式:
 *      无参构造:public 类名称(){}
 *      有参构造:public 类名称(参数类型 参数名,参数类型 参数名){方法体}
 *  注意事项:
 *      1、构造方法的名称必须和类的名称一致,包含大小写一致
 *      2、构造方法不需要写返回值类型,包括void
 *      3。构造方法没有返回值
 *      4、如果没有声明任何构造方法,编译器会默认提供一个无参数的构造方法供使用
 *      5、一旦编写任意构造方法,编译器将不提供无参构造方法
 *      6、如果已经创建有参构造,那么无参构造默认不存在,需要手动定义无参构造
 */
public class Demo01_ConstructorTest {
    public static void main(String[] args) {
        //无参构造创建对象
        User u1 = new User();
        //给对象的属性设置属性值
        u1.setName("周海媚");
        u1.setAge(22);
        //获取对象的属性值
        System.out.println(u1.getName());
        System.out.println(u1.getAge());
        System.out.println("--------------------");
        //有参构造创建对象
        User u2 = new User("邵美琪",22);
        //获取对象的属性值
        System.out.println(u2.getName());
        System.out.println(u2.getAge());
    }
}
2.5 定义标准的类
- 定义一个标准的类
  - 1、所有的成员变量都需要使用private关键字修饰
  - 2、为每一个成员变量编写一对setter和getter方法
  - 3、编写一个无参数的构造方法
  - 4、编写一个全参数的构造方法
  - 5、这样标准的类,也叫作JavaBean(Java豆子)
/**
 * 定义一个标准的类
 *  1、所有的成员变量都需要使用private关键字修饰
 *  2、为每一个成员变量编写一朵settrt和getter方法
 *  3、编写一个无参数的构造方法
 *  4、编写一个全参数的构造方法
 *  这样标准的类,也叫作JavaBean(Java豆子)
 */
public class Student {
    //成员变量
    private String username;
    private int age;
    private String address;
    //无参构造
    public Student() {
    }
    //全参构造
    public Student(String username, int age, String address) {
        this.username = username;
        this.age = age;
        this.address = address;
    }
    //setter和getter方法
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}
/**
 * 测试保准类
 */
public class Demo01_StudentTest {
    public static void main(String[] args) {
        //无参构造
        Student s1 =  new Student();
        s1.setUsername("古力娜扎");
        s1.setAge(22);
        s1.setAddress("新疆");
        System.out.println("姓名是:"+s1.getUsername()+",年龄是:"+s1.getAge()+",籍贯是:"+s1.getAddress());
        System.out.println("-------------------------------");
        //全参构造
        Student s2 = new Student("迪丽热巴",18,"新疆");
        System.out.println("姓名是:"+s2.getUsername()+",年龄是:"+s2.getAge()+",籍贯是:"+s2.getAddress());
        s2.setAge(19);
        System.out.println("姓名是:"+s2.getUsername()+",年龄是:"+s2.getAge()+",籍贯是:"+s2.getAddress());
    }
}



















