JavaSE-06 [面向对象OOP + 封装]
第一章 面向对象思想
1.1 面向过程和面向对象
- 面向过程: 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
- 面向对象: 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
- 总结
- 都是解决问题的思维方式,都是代码的组织方式
- 解决简单问题可以使用面向过程
- 解决复杂问题,宏观上使用面向对象把握,微观处理上仍然使用面向过程处理
面向对象编程的三大特征(抽象)
- 封装:需要让用户知道的暴露出来,不需要用户知道的隐藏起来,这就是封装–“该露的露,该藏的藏”
- 继承:一方面,继承的本质是对某一批类的抽象,从而实现对现实世界更好的封装。另一方面,代码的重用
- 多态:为了提高处理问题的灵活性,原始的抽象的事务,可以出现多种不同的形态展现
1.2 类和对象
什么是类
- 类: 类是一组相关属性和行为的集合,可以看成是一类事物的模板,使用事务特征和行为特征来描述该类事物
- 显示中,描述一类事物
- 属性:就是事物的状态信息
- 行为:就是事物的功能
什么是对象
- 对象:对象是一类事物的具体体现,对象是类的一个实例,必然具备该事物的属性和行为
- 现实中。一类事物的一个实例,就是一个对象
类和对象的关系
- 关系:
- 类可以看做是一个模板,或者图纸,系统根据类的定义来创造出对象
- 类是对一类事物的描述,是抽象的
- 对象是一类事物的实例,是具体的
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();
}
}
成员变量的默认值
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 对象内存图
-
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
}
}
使用对象类型作为方法的返回值
/**
* 类和对象的关系---内存图
* 使用对象类型作为方法的返回值
*/
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;
}
}
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 封装的定义
面向对象的三大特征:封装、继承、多态
封装的定义:就是将一些细节信息隐藏起来,对外界不可见
封装性在Java中的体现:方法是一种封装、private关键字也是一种封装
2.2 private关键字
private关键字:是用于对需要保护的成员变量进行修饰。
一旦使用了private关键字,那么在本类当中仍可以随意访问,但是在本类之外就不能访问。
如果想访问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());
}
}