面向对象和面向过程的思想对比 :
面向过程 :是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的
面向对象 :是一种以对象为中心的编程思想,通过指挥对象实现具体的功能
1.1 类和对象的关系
客观存在的事物皆为对象 ,所以我们也常常说万物皆对象。
-
-
类的理解
-
类是对现实生活中一类具有共同属性和行为的事物的抽象
-
类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
-
简单理解:类就是对现实事物的一种描述
-
-
类的组成
-
属性:指事物的特征,例如:手机事物(品牌,价格,尺寸)
-
行为:指事物能执行的操作,例如:手机事物(打电话,发短信)
-
-
-
类和对象的关系
-
类:类是对现实生活中一类具有共同属性和行为的事物的抽象
-
对象:是能够看得到摸的着的真实存在的实体
-
简单理解:类是对事物的一种描述,对象则为具体存在的事物
-
1.2 类的定义【应用】
类的组成是由属性和行为两部分组成
-
属性:在类中通过成员变量来体现(类中方法外的变量)
-
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)
类的定义步骤:
① 定义类
② 编写类的成员变量
③ 编写类的成员方法
/*
类文件:
*/
public class Student {
// 属性 : 姓名, 年龄
// 成员变量: 跟之前定义变量的格式一样, 只不过位置发生了改变, 类中方法外
String name;
int age;
// 行为 : 学习
// 成员方法: 跟之前定义方法的格式一样, 只不过去掉了static关键字.
public void study(){
System.out.println("学习");
}
}
1.3 对象的创建和使用
-
创建对象的格式:
-
类名 对象名 = new 类名();
-
-
调用成员的格式:
-
对象名.成员变量
-
对象名.成员方法();
-
-
示例代码 :
/*
测试文件:
*/
package com.itheima.object1;
public class TestStudent {
/*
创建对象的格式:
类名 对象名 = new 类名();
调用成员变量的格式:
对象名.变量名
调用成员方法的格式:
对象名.方法名();
*/
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 = 23;
System.out.println(stu.name); // 张三
System.out.println(stu.age); // 23
// 对象名.方法名();
stu.study();
// com.itheima.object1.Student@b4c966a
// 全类名(包名 + 类名)
System.out.println(stu);
}
}
1.4 案例-手机类的创建和使用
需求 :首先定义一个手机类,然后定义一个手机测试类,在手机测试类中通过对象完成成员变量和成员方法的使用
分析 :
-
成员变量:品牌, 价格
-
成员方法:打电话, 发短信
-
示例代码:
类文件:
package com.itheima.test1;
public class Phone {
// 品牌, 价格
String brand;
int price;
// 打电话, 发短信
public void call(String name){
System.out.println("给"+name+"打电话");
}
public void sendMessage(){
System.out.println("群发短信");
}
}
/*
测试文件:
*/
package com.itheima.test1;
public class TestPhone {
public static void main(String[] args) {
// 1. 创建对象
Phone p = new Phone();
// 2. 给成员变量进行赋值
p.brand = "大米";
p.price = 2999;
// 3. 打印赋值后的成员变量
System.out.println(p.brand + "..." + p.price);
// 4. 调用成员方法
p.call("阿强");
p.sendMessage();
}
}
2. 对象内存图
2.1 单个对象内存图【理解】
2.2 多个对象内存图【理解】
-
总结:
多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自的内存区域中,成员方法多个对象共用的一份
2.3 多个对象指向相同内存图【理解】
-
总结 :
当多个对象的引用指向同一个内存空间(变量所记录的地址值是一样的)
只要有任何一个对象修改了内存中的数据,随后,无论使用哪一个对象进行数据获取,都是修改后的数据。
3. 成员变量和局部变量
3.1 成员变量和局部变量的区别
-
类中位置不同:成员变量(类中方法外)局部变量(方法内部或方法声明上)
-
内存中位置不同:成员变量(堆内存)局部变量(栈内存)
-
生命周期不同:成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而存在,醉着方法的调用完毕而消失)
-
初始化值不同:成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)
4. 封装
4.1 private关键字
概述 : private是一个修饰符,可以用来修饰成员(成员变量,成员方法)
特点 : 被private修饰的成员,只能在本类进行访问,针对private修饰的成员变量,如果需要被其他类使用, 提供相应的操作
提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰
示例代码:
/*
学生类文件:
*/
public class Student {
//成员变量
String name;
private int age;
//提供get/set方法
public void setAge(int a) {
if(a<0 || a>120) {
System.out.println("你给的年龄有误");
} else {
age = a;
}
}
public int getAge() {
return age;
}
//成员方法
public void show() {
System.out.println(name + "," + age);
}
}
/*
学生测试类:
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
//给成员变量赋值
s.name = "林青霞";
s.setAge(30);
//调用show方法
s.show();
}
}
4.2 private关键字的使用
-
需求:
-
定义标准的学生类,要求name和age使用private修饰
-
并提供set和get方法以及便于显示数据的show方法
-
测试类中创建对象并使用,最终控制台输出 林青霞,30
-
-
示例代码:
/*
学生类:
*/
class Student {
//成员变量
private String name;
private int age;
//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 show() {
System.out.println(name + "," + age);
}
}
/*
学生测试类:
*/
public 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());
System.out.println(s.getName() + "," + s.getAge());
}
}
4.3 this关键字【应用】
概述 : this修饰的变量用于指代成员变量,其主要作用是(区分局部变量和成员变量的重名问题)
-
方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
-
方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量
代码实现 :
/*
类文件:
*/
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void show() {
System.out.println(name + "," + age);
}
}
4.4 this内存原理【理解】
-
注意 : this代表当前调用方法的引用,哪个对象调用的方法,this就代表哪一个对象
-
图解 :
4.5 封装思想
-
封装概述 是面向对象三大特征之一(封装,继承,多态) 是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
-
封装原则 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问 成员变量private,提供对应的getXxx()/setXxx()方法
-
封装好处 通过方法来控制成员变量的操作,提高了代码的安全性 把代码用方法进行封装,提高了代码的复用性
5. 构造方法
5.1 构造方法的格式和执行时机
-
格式注意 :
-
方法名与类名相同,大小写也要一致
-
没有返回值类型,连void都没有
-
没有具体的返回值(不能由retrun带回结果数据)
-
-
执行时机 :
-
创建对象的时候调用,每创建一次对象,就会执行一次构造方法
-
不能手动调用构造方法
-
-
示例代码:
/*
类文件:
*/
public class Student {
private String name;
private int age;
//构造方法
public Student() {
System.out.println("无参构造方法");
}
public void show() {
System.out.println(name + "," + age);
}
}
/*
测试类:
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
s.show();
}
}
5.2 构造方法的作用
-
用于给对象的数据(属性)进行初始化
package com.itheima.constructor;
/*
类文件:
*/
public class Student {
/*
格式:
1. 方法名需要跟类名相同, 大小写也要一致
2. 没有返回值类型, 连void都没有
3. 没有具体的返回值(不能由return带回具体的结果)
*/
private String name;
private int age;
// 1. 如果一个类中没有编写任何构造方法, 系统将会提供一个默认的无参数构造方法
public Student(){}
// 2. 如果手动编写了构造方法, 系统就不会再提供默认的无参数构造方法了
public Student(String name, int age){
this.name = name;
this.age = age;
System.out.println("我是Student类的构造方法");
}
public void show(){
System.out.println(name + "..." + age);
}
}
package com.itheima.constructor;
/*
测试文件:
*/
public class TestStudent {
public static void main(String[] args) {
Student stu1 = new Student("张三",23);
stu1.show();
Student stu2 = new Student();
}
}
5.3 构造方法的注意事项
构造方法的创建 :
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法
构造方法的创建 :
如果没有定义构造方法,系统将给出一个默认的无参数构造方法如果定义了构造方法,系统将不再提供默认的构造方法
推荐的使用方式 :
无论是否使用,都手动书写无参数构造方法,和带参数构造方法
5.4 标准类的代码编写和使用
代码 :
package com.itheima.test3;
/*
方法类:
JavaBean类: 封装数据
*/
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;
}
public void show(){
System.out.println(name + "..." + age);
}
}
package com.itheima.test3;
/*
测试类:
*/
public class TestStudent {
public static void main(String[] args) {
// 1. 无参数构造方法创建对象, 通过setXxx方法给成员变量进行赋值
Student stu1 = new Student();
stu1.setName("张三");
stu1.setAge(23);
stu1.show();
// 2. 通过带参数构造方法, 直接给属性进行赋值
Student stu2 = new Student("李四",24);
stu2.show();
}
}
day07课后作业题
代码题
1.训练案例1
1.1. 训练描述:【Scanner,类和对象】
一、 实现从控制台接收一个学员信息,并存储到一个对象中
二、 打印这个对象的所有属性值。
1.2.要求描述
l 设计,并定义一个学员类:Student,要求有以下属性:
• 学员编号(String)
• 姓名(String)
• 性别(String)
• 身高(double)
• 年龄(int)
使用封装的原则,并提供无参和全参的构造方法。
1 定义MainApp类,并包含main()方法。
2 程序启动后,应分别提示用户输入学员编号、姓名等信息。
例如控制台显示:
• 请输入学员编号:
• ....
• 请输入学员姓名:
• ....
• .................
数据接收到程序中,并定义局部变量存储;
创建Student对象,通过构造方法将所有数据存储到Student对象中;
在main方法中获取并打印对象中的每个属性值。
代码实现:
/*
类文件:
*/
package com.heima.meiri.day7.mrb1;
public class Student {
private String Bianhao ;
private String Xingming ;
private String Xingbie ;
private double Shengao;
private int Age;
public Student() {
}
public Student(String bianhao, String xingming, String xingbie, double shengao, int age) {
Bianhao = bianhao;
Xingming = xingming;
Xingbie = xingbie;
Shengao = shengao;
Age = age;
}
public String getBianhao() {
return Bianhao;
}
public void setBianhao(String bianhao) {
Bianhao = bianhao;
}
public String getXingming() {
return Xingming;
}
public void setXingming(String xingming) {
Xingming = xingming;
}
public String getXingbie() {
return Xingbie;
}
public void setXingbie(String xingbie) {
Xingbie = xingbie;
}
public double getShengao() {
return Shengao;
}
public void setShengao(double shengao) {
Shengao = shengao;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
public void show(){
System.out.println("学号:"+Bianhao);
System.out.println("姓名:"+Xingming);
System.out.println("性别:"+Xingbie);
System.out.println("身高:"+Shengao);
System.out.println("年龄:"+Age);
}
}
/*
测试文件:
*/
package com.heima.meiri.day7.mrb1;
import java.util.Scanner;
public class TestStudent {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
Student s=new Student();
System.out.println("请输入学员编号:");
String i1 = sc.nextLine();
s.setBianhao(i1);
System.out.println("请输入学员姓名:");
String i2 = sc.nextLine();
s.setXingming(i2);
System.out.println("请输入学员性别:");
String i3 = sc.nextLine();
s.setXingbie(i3);
System.out.println("请输入学员身高:");
double i4 = sc.nextDouble();
s.setShengao(i4);
System.out.println("请输入学员年龄:");
int i5 = sc.nextInt();
s.setAge(i5);
s.show();
System.out.println("-------");
Student st=new Student(i1,i2,i3,i4,i5);
st.show();
}
}
运行效果:
2.训练案例2
2.1.训练描述
分析以下需求,并用代码实现
• 1.项目经理类Manager
• 属性:
• 姓名name
• 工号id
• 工资salary
• 奖金bonus
• 行为:
• 工作work()
• 2.程序员类Coder
• 属性:
• 姓名name
• 工号id
• 工资salary
• 行为:
• 工作work()
2.2:要求描述
要求:
1.按照以上要求定义Manager类和Coder类,属性要私有,生成空参、有参构造,setter和getter方法
2.定义测试类,在main方法中创建该类的对象并给属性赋值(演示两种方法:setter方法和构造方法)
3.调用成员方法,打印格式如下:
工号为123基本工资为15000奖金为6000的项目经理一龙正在努力的做着管理工作,分配任务,检查员工提交上来的代码.....
工号为135基本工资为10000的程序员方便正在努力的写着代码......
/*
类文件1:
*/
package com.heima.meiri.day7.mrb2;
public class Manager {
private String name;
private String id;
private int salary;
private int bonus;
public Manager() {
}
public Manager(String name, String id, int salary, int bonus) {
this.name = name;
this.id = id;
this.salary = salary;
this.bonus = bonus;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
public void work(String name){
System.out.println("正在努力的做着管理工作,分配任务,检查"+name+"的代码");
}
public void show(){
System.out.print("工号为"+id+"基本工资为"+salary+"奖金为"+bonus+"的项目经理"+name);
work("小张");
}
}
/*
类文件2:
*/
package com.heima.meiri.day7.mrb2;
public class Coder {
private String name;
private String id;
private int salary;
public Coder() {
}
public Coder(String name, String id, int salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public void work(){
System.out.println("写代码");
}
public void show(){
System.out.print("工号为"+id+"基本工资为"+salary+"程序员"+name+"正努力");
work();
}
}
/*
测试文件:
*/
package com.heima.meiri.day7.mrb2;
public class Test {
public static void main(String[] args) {
Coder c=new Coder();
c.setId("0203001");
c.setName("lpj");
c.setSalary(10000);
c.show();
System.out.println("------");
Coder c1=new Coder("lpj","020",9999);
c1.show();
System.out.println("----------------------------");
Manager m=new Manager();
m.setBonus(3000);
m.setId("030");
m.setName("pj");
m.setSalary(15000);
m.show();
System.out.println("------");
Manager m1=new Manager("l","030",15000,4000);
m1.show();
}
}
运行效果:
day07课后扩展作业题
单选题
1:下列信息中包含的内容不是类与对象关系的是(C )
A: 学生和小明同学 B: 电脑和联想Y430电脑 C: 猫和狗C D: 手机和华为P20手机
2:下列描述正确的是(C )
A: 类与对象之间是包含关系,类包含对象。 B: 类与对象之间是等价关系,类和对象其实是同一个概念。 C: 对象是类的实例,类是对象的模板。 D: 通过一个类,只能创建一个对象。
3:下列描述正确的是(D )
A: 类是描述事物的属性和行为的特征而对象是一类事物的模板 B: 类是事物的具体体现而对象是一组相关属性和行为的集合 C: 类和对象可以看成是一类事物的模板* D: 类是对一类事物的描述,是抽象的对象是一类事物的实例,是具体的
4:下列描述错误的是(D )
A: 在方法中的变量是局部变量 B: 局部变量随着方法的调用而存在,随着方法的调用结束而消失 C: 成员变量在类中、方法外 D: 局部变量有默认的初始化值
5:下列代码的运行结果是(C )
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Demo{
public static void main(String [] args){
Student s = new Student();
s.setName("小丽");
s.setAge(16);
System.out.println(s.getName() + "---" + s.getAge());
}
}
A: 语法错误,编译报错。 B: 小丽 --- 16 C: null --- 16 D: 小丽 --- 0
多选题
6:下列描述正确的是(ACD )
A: 面向对象思想是基于面向过程思想而来的,强调的是对象
B: 面向对象思想关注的是功能的每一个步骤
C: 面向对象思想完成一个功能,关注的是功能的结果,而不是每一个步骤,强调的是对象
D: 面向对象思想,关注的是对象,让对象帮我们完成一个功能,强调的是对象
7:下列描述正确的是(ABD )
A: 类的{}中定义的是类的成员,可以有成员变量和成员方法。
B: 定义成员变量时,可以不给变量赋值。
C: 必须先定义成员变量,再定义成员方法。*
D: 成员变量的名字可以和局部变量的名字相同。
8:下列说法正确的是(ABDC )
A: 当成员变量和局部变量重名时,可以使用this来区分。
B: this可以调用本类的成员变量和成员方法。*
C: this表示本类对象的引用。
D: 在方法中访问本类成员变量(非重名),可以省略this不写。
9:关于下列代码描述正确的是( BC)
public class Demo{
int num1;
public void method(){
int num2;
System.out.println(num1);
System.out.println(num2);
}
}
public class Test{
public static void main(String[] args){
Demo d = new Demo();
d.method();
}
}
A: Demo中num1和num2都是成员变量
B: Demo中变量num1是成员变量,method方法中变量num2是局部变量
C: 编译报错,因为num2是局部变量,没有赋值,不能直接使用
D: 调用Demo中的method的方法会在控制台输出:0 0
10:下列横线处填写Person类的构造方法的正确语法格式是(BC )
public class Person{
private String name;
__________________
}
A
public void Person(String name){
name = name;
}
B
public Person(){
}
C
public Person(String name){
this.name = name;
}
D
public Person(String name){
return name;
}
代码题
1.训练案例1
1.1.训练描述
分析以下需求,并用代码实现
1.猫类Cat
属性:
毛的颜色color
品种breed
行为:
吃饭eat()
抓老鼠catchMouse()
2.狗类Dog
属性:
毛的颜色color
品种breed
行为:
吃饭eat()
看家lookHome()
要求:
1.按照以上要求定义Cat类和Dog类,属性要私有,生成空参、有参构造,setter和getter方法
2.定义测试类,在main方法中创建该类的对象并给属性赋值(演示两种方法:setter方法和构造方法)
3.调用成员方法,测试代码效果
1.2:案例效果
打印格式如下:
花色的波斯猫正在吃鱼.....
蓝色的英国短毛猫正在逮老鼠.....
黑色的德牧正在啃骨头.....
黑色的藏獒正在看家.....
/*
类文件1:
*/
package com.heima.meiri.day7.kz.kz1;
public class Cat {
private String color;
private String breed;
public Cat() {
}
public Cat(String color, String breed) {
this.color = color;
this.breed = breed;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public void Gn1(String eat){
System.out.println(color+"的"+breed+"正在"+eat);
}
public void Gn2(String catchMouse){
System.out.println(color+"的"+breed+"正在"+catchMouse);
}
}
/*
类文件2:
*/
package com.heima.meiri.day7.kz.kz1;
public class dog {
private String color;
private String breed;
public dog() {
}
public dog(String color, String breed) {
this.color = color;
this.breed = breed;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public void Gn1(String eat){
System.out.println(color+"的"+breed+"正在"+eat);
}
public void Gn2(String lookHome){
System.out.println(color+"的"+breed+"正在"+lookHome);
}
}
/*
测试代码:
*/
package com.heima.meiri.day7.kz.kz1;
public class Test {
public static void main(String[] args) {
Cat c=new Cat();
c.setColor("红色的");
c.setBreed("波斯猫");
c.Gn1("吃肉");
c.Gn2("抓老鼠");
System.out.println("...");
Cat c1=new Cat("红色的","大花猫");
c1.Gn1("吃鱼");
c1.Gn2("爬树");
System.out.println("-----");
dog d=new dog();
c.setColor("黄色的");
c.setBreed("哈士奇");
c.Gn1("啃骨头");
c.Gn2("看家");
System.out.println("...");
dog d1=new dog("黑色的","二哈");
d1.Gn1("吃屎");
d1.Gn2("拆家");
}
}
运行效果:
2.训练案例2
2.1.训练描述
请设计一个汽车类,模拟出司机开车载乘客兜风的场景;在测试类中分别使用空参数构造方法创建对象和带参数构造方法创建对象并调用run方法,测试效果;
要求:
1:汽车类包含的成员变量
品牌,价格,颜色
2:汽车类包含的成员方法
getter/setter方法
run方法,有字符串类型的司机和乘客两个形参,无返回值
3:有带参数构造方法和空参数构造方法
2.2:案例效果
/*
类文件:
*/
package com.heima.meiri.day7.kz.ka2;
public class Car {
private String name;
private String color;
private String pinpai;
private int Yuan;
public Car() {
}
public Car(String name, String color, String pinpai, int yuan) {
this.name = name;
this.color = color;
this.pinpai = pinpai;
Yuan = yuan;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getPinpai() {
return pinpai;
}
public void setPinpai(String pinpai) {
this.pinpai = pinpai;
}
public int getYuan() {
return Yuan;
}
public void setYuan(int yuan) {
Yuan = yuan;
}
public void show(String name){
System.out.println(this.name+"开着价值"+Yuan+"万的"+color+pinpai+"带着"+name+"去兜风");
}
}
/*
测试文件:
*/
package com.heima.meiri.day7.kz.ka2;
public class TestCar {
public static void main(String[] args) {
Car c=new Car();
c.setName("刘备");
c.setColor("红色");
c.setPinpai("兰博基尼");
c.setYuan(50);
c.show("孙尚香");
System.out.println("----");
Car c1=new Car("吕布","黄色","迈巴赫",66);
c1.show("貂蝉");
}
}
运行效果: