上篇回顾
上篇的内容不知道小伙伴们学习的怎样,我这里出几个问题帮助下大家巩固一下,大家看看能不能直接回答出来。方法的定义格式?
return关键字的作用?
有返回值方法的调用方式?无返回值方法调用方式?
方法参数为基本数据类型时的参数传递方式?
方法参数为引用数据类型时的参数传递方式?
方法重载的条件?
学习目标面向对象
内容
1 面向对象思想概述
1.1 面向过程与面向对象
面向过程:
分析出解决问题所需要的步骤,按每个步骤一步步完成。
面向过程开发,代码的组成单位是方法。
代表语言:C语言
面向对象:
分析出问题所涉及的所有对象,再指挥这些对象解决问题。
面向对象开发,代码的组成单位是类。
代表语言:Java举例:五子棋游戏
面向过程的设计思路:
首先分析问题的步骤:
1、开始游戏
2、黑子先走
3、绘制画面
4、判断输赢
5、轮到白子
6、绘制画面
7、判断输赢
8、返回步骤2,
9、输出最后结果。
然后把上面每个步骤用不同的方法来实现。
面向对象的设计思路:
首先分析和设计参与者,整个游戏有:
1、棋子对象(黑白棋2个对象)
2、棋盘对象
3、规则系统
然后调用对象完成各自的功能:
棋子对象负责走棋,棋盘对象负责绘制和更新画面,规则系统负责判断输赢。
1.2 面向对象的思想特点
面向对象特点:
1、更接近现实世界,符合我们的思考习惯。
2、明确功能归属,更容易解决大型的复杂的业务逻辑。
3、从代码角度看,面向对象程序易维护、易复用、易扩展。
4、缺点:性能比面向过程低 。
2 类和对象的概述
面向对象的语言中最重要的两个概念:类和对象。
2.1 什么是类
类:类是对同一类事物的共同特征(属性、行为)的描述。
比如汽车类,动物类,手机类等。
属性:就是事物特征的描述信息。(类中对应的是成员变量)
比如人有身高,体重,姓名等属性,手机有颜色,价格,品牌等属性。
行为:就是事物能够做什么,有什么功能。(类中对应的是成员方法)
比如人有走路,说话,吃饭等行为,手机有拍照,打电话等功能。
2.2 什么是对象
对象是某一类事物的具体体现,是类真实存在的一个实例。
举例:学生张三是学生类的一个对象。
2.3 类和对象的关系
1、类是对事物的描述,是一个抽象的概念,没有真实存在的。
2、对象是事物的具体实例,是真实存在的。
3、编程开发中,需要先有类,才能创建该类的对象。一个类能创建出千千万万个对象。
简单理解:类是对象的模板,对象是类的实例,通过类创建对象。
3 类的定义和使用
3.1 类的定义格式访问修饰符 class 类名{
// 类的五大成分:
// 类的成员变量
// 成员方法
// 构造方法
// 内部类
// 代码块{}
}
3.2 成员变量
用于描述类的属性。
与变量的定义格式一样,只是定义位置发生了改变:定义在类中方法外。
成员变量可以不手动初始化就使用,因为有默认初始化值。
3.3 成员方法:
用于描述类的行为或功能。
与之前学的方法的定义一样,只是少了static关键字。
示例代码:/**
* 手机类 Phone:
* 成员变量:
* 品牌(brand)
* 价格(price)
*
* 成员方法:
* 打电话(call)
* 发短信(sendMessage)
*/
public class Phone{
// 成员变量
String brand; // 品牌
int price; // 价格
// 成员方法(打电话)
public void call(){
System.out.println("打电话");
}
// 成员方法(发短信)
public void sendMessage(){
System.out.println("发短信");
}
}/**
* 需求:
* 定义一个学生类Student,包含:
* 1、姓名(name)和年龄(age)属性
* 2、学习(study)和吃饭(eat)的行为
*/
3.4 对象的使用创建对象的格式:类名 对象名 = new 类名();
调用成员的格式:
对象名.成员变量
对象名.成员方法();/**
* 类的使用示例代码
*/
public class PhoneDemo{
public static void main(String[] args){
// 创建对象
Phone p = new Phone();
// 使用成员变量
System.out.println(p.brand);
System.out.println(p.price);
// 为成员变量赋值
p.brand = "小米";
p.price = 2999;
System.out.println(p.brand);
System.out.println(p.price);
// 使用成员方法
p.call();
p.sendMessage();
}
}
3.5 学生类案例
需求:
1、定义一个学生类,包含:
成员变量:姓名,年龄
成员方法:学习,做作业
2、定义学生测试类,在测试类中创建学生类的对象,调用成员变量和成员方法。
案例代码:/**
* 创建学生类
*/
public class Student{
// 成员变量
String name; // 姓名
int age; // 年龄
// 成员方法
public void study(){
System.out.println("好好学习,天天向上");
}
public void doHomework(){
System.out.println("键盘敲烂,月薪过万");
}
}/**
* 学生测试类
*/
public class StudentDemo{
public static void main(String[] args){
// 创建对象
Student s = new Student();
// 使用对象
System.out.println(s.name + "," + s.age);
s.name = "林志玲";
s.age = 30;
System.out.println(s.name + "," + s.age);
s.study();
s.doHomework();
}
}/**
* 需求:定义汽车类Car
* 成员变量:
* 颜色(color)
* 品牌(brand)
* 成员方法:
* 启动(start)
*/
4 对象内存图
4.1 单个对象内存图(1)、Student s = new Student(); 对象在内存中的创建过程 ?
1. 方法区加载类的定义信息。
2. 在堆内存中开辟空间,创建Student对象,产生地址值,并完成成员变量的初始化。
3. 将堆中产生的Student对象的地址值赋给栈内存中的变量s, 便于通过地址操作成员变量或方法。
(2)、成员变量存放在哪块内存?
成员变量在堆内存,有默认值。
局部变量存在于栈内存中,需要使用前完成初始化。
4.2 多个对象内存图
创建多个对象,内存地址不一样,堆内存中维护的成员变量是各自一份数据。但是方法区的类信息只加载一次。
4.2 多个对象指向相同内存图
多个对象指向相同内存图,就是说多个对象存储了相同的内存地址值,任意一个对象改变了堆内存中的成员变量值,其他的所有对象都会受到影响,访问到就是修改后的值。
5 成员变量和局部变量
成员变量:
定义在类中,方法外,属于类的成员,使用对象名访问。
局部变量:
定义在方法内或者形参列表上的变量。public class Test{
// 成员变量(定义在类中,方法外)
String name;
int age;
// 定义在方法内 或者 形参列表上:局部变量(a , b , c )
public void sum(int a, int b){
int c = a + b;
System.out.println(c);
}
}
成员变量和局部变量的区别:
定义位置内存位置生命周期初始化值作用范围成员变量在类中,方法外堆内存随对象的创建而创建,随对象的消失而消失。有默认值能被类中的其他成员使用。
局部变量方法中或参数列表中栈内存随方法的调用而创建,方法的结束而消失。没有默认值,必须先赋值后使用只能在变量所在的方法内使用。
成员变量:能被类中的其他成员使用。(变量需要被多个方法共享的时候,定义成成员变量)
在方法执行过程中,暂时需要用到,定义成局部变量
6 private和this关键字
6.1 private关键字
private的特点:
1、private是权限修饰符,代表私有的意思。
2、可以修饰成员变量和成员方法。
3、被private修饰的成员只能在本类中使用。// 使用private修饰age变量
public class Student{
private int age; // 该变量只能在本类中使用
// 设置值setAge(int a){}
// 获取 int getAge(){}
}
为了在其他类中能使用被private修饰的成员变量,一般会提供一对公有(public修饰)的getter和setter方法,用于获取和设置成员变量的值。/**
* 学生类
*/
public class Student{
// 成员变量
String name;
// 私有成员变量
private int age;
// setter方法,用于设置成员变量的值
public void setAge(int a){
// 可以在方法内进行数据合法性检验
if(a<0 || a>120) {
System.out.println("你给的年龄有误");
} else {
age = a;
}
}
// getter方法,用于获取成员变量的值
public int getAge(){
return age;
}
// 成员方法
public void show(){
System.out.println(name + "," + age);
}
}
/**
* 学生测试类
*/
class StudentDemo{
public static void main(String[] args){
// 创建对象
Student s = new Student();
// 给成员变量赋值
s.name = "林志玲";
s.setAge(30);
// 调用方法
s.show();
}
}
6.2 private的使用
标准类的定义步骤:
1、使用private修饰成员变量。
2、提供public修饰的getter和setter方法。
getter和setter方法的命名规范:
getter方法用于获取成员变量的值,所以方法有返回值,方法名为:get+成员变量名首字母大写。
String getName() int getAge()
setter方法用于设置成员变量的值,所以方法有参数,方法名为:set+成员变量名首字母大写。
setName(String name)setAge(int a)
案例代码:/**
* 需求:
* 1. 定义标准的学生类,要求name和age使用private修饰,并提供set和get方法,以及显示数据的show方法。
* 2. 测试类中创建对象并使用,最终在控制台输出name和age的值。
*/
public class Student{
// 私有成员变量
private String name;
private int age;
// 公有getter 和 setter方法
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 show(){
System.out.println(name + "," + age);
}
}
/**
* 学生测试类
*/
class StudentDemo{
public static void main(String[] args){
// 创建对象
Student s = new Student();
// 使用set方法给成员变量赋值
s.setName("林志玲");
s.setAge(30);
s.show();
// 使用get方法获取成员变量的值
System.out.println(s.getName() + "," + s.getAge());
}
}
6.3 this关键字
1、变量的访问规则?
当方法内的局部变量和类的成员变量同名时,变量的访问遵循就近原则。
2、this关键字的作用(使用场景)?
当方法内局部变量和类的成员变量同名时,使用this关键字访问类的成员变量。
格式:this.成员变量名
3、this关键字的内存原理?
this存储了当前对象的内存地址。
this代表当前对象的引用,哪个对象在调用方法,this就代表那个对象。/**
* this:代表当前对象的引用,哪个对象调方法,this就代表谁。
*/
public class Student{
public void study(){
System.out.println("this值:"+this); // Student@3fb6a447
}
}
class ThisDemo{
public static void main(String[] args){
Student s = new Student();
System.out.println("对象s的值:"+s); // Student@3fb6a447
s.study();
}
}
使用this改造学生类public class Student{
// 私有成员变量
private String name;
private int age;
// 公有getter 和 setter方法
public void setName(String name){
// 参数名和成员变量相同,使用this访问成员变量name
this.name = name;
}
public String getName(){
// 此处成员变量name没有重名,可以不用this来访问
// return this.name;
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void show(){
System.out.println(name + "," + age);
}
}
快速生成getter和setter方法
快捷键:Alt + Insert
7 封装
7.1 封装的概述
封装是程序设计思想
封装是面向对象的三大特征之一。面向对象的三大特性是:封装、继承、多态。
7.2 封装的原则
原则:对类中的成员进行合理隐藏,合理暴露。
合理隐藏:使用private私有类的成员变量或核心方法,不允许外部直接访问。
合理暴露:对私有的成员变量提供public修饰的get/set方法,既能保证数据安全,又能实现数据访问。
7.3 封装的好处
通过方法来控制成员变量的操作,提高了数据的安全性。 把代码用方法进行封装,提高了代码的复用性。
8 构造方法
8.1 构造方法概述
构造方法是一种特殊的方法,构造方法也叫构造函数或者构造器。
8.2 构造方法的格式修饰符 类名(参数列表){
// 初始化代码
}
构造方法特点:
1、构造方法没有返回值,连void也不能写,构造方法名和类名相同。
2、构造方法使用new关键字调用。
3、每创建一次对象,就会调用一次构造方法。/**
* 学生类
*/
public class Student{
private String name;
private int age;
// 无参构造方法
public Student(){
System.out.println("无参构造方法");
}
}
/**
* 测试类
*/
class StudentDemo{
public static void main(String[] args){
// 创建对象:使用new关键字调用构造方法,创建对象。
Student s = new Student();
// 每创建一个对象,就调用一次构造方法
Student s2 = new Student();
}
}
8.3 构造方法的作用
构造方法用于创建对象,并完成对象的初始化/**
* 学生类
*/
public class Student{
private String name;
private int age;
// 此处省略getter和setter方法
// 无参构造方法
public Student(){
System.out.println("无参构造方法");
}
// 有参构造方法(可以在构造方法中完成成员变量的初始化赋值)
public Student(String name, int age){
this.name = name;
this.age = age;
System.out.println("有参构造方法");
}
}
/**
* 测试类
*/
class StudentDemo{
public static void main(String[] args){
// 调用有参构造方法创建对象,并完成对象的初始化
Student s = new Student("张三", 18);
System.out.println(s.getName()); // 输出:张三
System.out.println(s.getAge()); // 输出:18
}
}
8.4 构造方法的注意事项
(1)、如果类中没有定义构造方法,系统会提供一个默认的无参构造方法。
(2)、如果类中定义了有参构造方法,那么系统将不再提供默认的无参构造方法。
这时如果还想使用无参构造方法创建对象,就必须手动添加无参构造方法。
(3)、构造方法是可以重载的。
建议:定义类时都手动给出无参构造方法。/**
* 定义学生类,提供无参和有参构造方法。
*/
public class Student{
private String name;
private int age;
// 此处省略getter和setter方法
// 无参构造方法
public Student(){}
// 有参构造方法,用于初始化成员变量name
public Student(String name){
this.name = name;
}
// 有参构造方法,用于初始化成员变量age
public Student(int age){
this.age = age;
}
// 满参构造方法:参数列表包含所有成员变量
public Student(String name,int age){
this.name = name;
this.age = age;
}
// 显示数据的方法
public void show(){
System.out.println(name + ":" + age);
}
}
/**
* 测试类
*/
class StudentDemo{
public static void main(String[] args){
// 调用无参构造方法创建对象
Student s1 = new Student();
s1.show();
// 调用有参构造方法,初始化name成员变量
Student s2 = new Student("隔壁老王");
s2.show();
// 调用有参构造方法,初始化age成员变量
Student s3 = new Student(30);
s3.show();
// 调用满参构造方法
Student s4 = new Student("隔壁老王",30);
s4.show();
}
}
快速生成构造方法
9 标准类的制作
步骤:1. 使用private私有成员变量。
2. 提供公有的getter和setter方法用于操作成员变量。
3. 提供无参和有参构造方法。
4. 根据类的其他需要需要添加成员方法。
/**
* 需求:定义一个标准学生类
*/
public class Student {
// 使用private私有成员变量。
private String name;
private int age;
// 提供公有的getter和setter方法用于操作成员变量。
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;
}
// 提供无参和有参构造方法。
// 无参构造方法
public Student(){
}
// 有参构造方法
public Student(String name,int age){
this.name = name;
this.age = age;
}
// 根据类的其他需要需要添加成员方法。
public void show() {
System.out.println(name + "," + age);
}
}
/**
* 测试类
*/
class StudentDemo {
public static void main(String[] args) {
// 方式1:使用setter方法完成成员变量的赋值
Student s1 = new Student();
s1.setName("林志玲");
s1.setAge(30);
s1.show();
// 方式2:使用满参构造方法完成成员变量的赋值
Student s2 = new Student("林志玲",30);
//s2 = new Student("林志玲",31);
s2.setAge(31);
s2.show();
}
}
给成员变量赋值的方式:
1、通过setXxx()方法。
2、通过有参构造方法。
使用区别:
构造方法一般用于创建对象并完成成员变量初始化赋值,setter方法一般用于代码执行过程中,改变对象的成员变量的值。
总结
面向过程强调步骤和过程,注重如何一步一步解决问题。(强调怎么做)
面向对象强调对象,即有哪些参与者,这些参与者各自要负责解决哪些问题。(强调谁来做)