JavaSE-06 【面向对象OOP--封装】

JavaSE-06 [面向对象+封装]

第一章 面向对象思想

1.1 面向过程和面向对象

  • 面向过程: 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
  • 面向对象: 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
  • 总结
    • 都是解决问题的思维方式,都是代码的组织方式
    • 解决简单问题可以使用面向过程
    • 解决复杂问题,宏观上使用面向对象把握,微观处理上仍然使用面向过程处理

1.2 面向对象编程的三大特征(抽象)

  • 封装:需要让用户知道的暴露出来,不需要用户知道的隐藏起来,这就是封装–“该露的露,该藏的藏”
  • 继承:一方面,继承的本质是对某一批类的抽象,从而实现对现实世界更好的封装。另一方面,代码的重用
  • 多态:为了提高处理问题的灵活性,原始的抽象的事务,可以出现多种不同的形态展现

1.3 类和对象

  • 什么是类
类: 类是一组相关属性和行为的集合,
	可以看成是一类事物的模板,
	使用事务特征和行为特征来描述该类事物 
	
现实中,描述一类事物
	属性:就是事物的状态信息
	行为:就是事物的功能
  • 什么是对象
对象:对象是一类事物的具体体现,对象是类的一个实例,
	  必然具备该事物的属性和行为 
	  现实中,一类事物的一个实例,就是一个对象
  • 类和对象的关系
关系:
	1、类可以看做是一个模板,或者图纸,
		系统根据类的定义来创造出对象
	2、类是对一类事物的描述,是抽象的 
	3、对象是一类事物的实例,是具体的 

在这里插入图片描述

1.4 类的定义

  • 类的定义
类是现实世界的一类事物
   	属性:事物的状态信息
   	行为:事物的功能和作用
   	
Java中用Class描述事物也是如此
	成员变量:对应事物的属性
   	成员方法:对应事物的行为
   	
定义类:
   就是定义类的成员,包括成员属性和成员方法
成员变量的位置:
   定义在类中,方法外
成员方法的位置:
   定义在类中,与之前的方法不一致的是,去掉了static
  • 类的定义格式
public class 类的名称{
    //成员变量
    //成员方法
}
/**
 * 类的定义
 *  定义一个类,用于模拟学生事物,由两部分组成
 *      学生属性:年龄。升高。体重...
 *      学生行为:学习、运动、睡觉...
 *  对应在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.5 对象的使用

  • 对象的使用格式
一般情况下,一个类并不能直接使用,需要根据类创建一个对象才能使用

创建对象的步骤:
  - 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();
    }
}

1.6 类与对象的练习

  • 定义一个类,用来模拟”电脑“事物
//模板类
public class Computer {
    //定义成员属性
    String brand;//品牌
    double price;//价钱
    String color;//颜色
    //定义成员方法
    public void playGame(){
        System.out.println("电脑可以打游戏!");
    }
    public void lookMovie(){
        System.out.println("电脑可以看电影!");
    }
    public void chart(){
        System.out.println("电脑可以聊天!");
    }
}
/**
 * 类和对象的练习
 */
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.7 对象内存图理解

- 对象内存图理解:
  -  1、先加载Computer类信息`:属性与方法
  -  2、进行默认初始化,再显示初始化(double price = 5000.0)
		最后执行构造方法初始化` 
  -  3、把堆中的地址赋给computer,computer就指向对象,
		computer是对象的引用`,或者叫对象名
  -  4、当执行到方法时,就会开辟独立的空间(栈)` 
  -  5、方法执行完毕/执行到return就会返回到调用方法的地方`
  -  6、继续执行后续代码 
  -  7、当main方法(栈)`执行完毕,程序退出  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIm2zNzs-1686187958346)(photo/JavaSE06_面向对象之封装.assest/1664705217813.png)]

1.8 成员变量和局部变量

  • 局部变量和成员变量区别
- 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());
    }
}