Day07
面向对象基础
面向对象和面向过程的思想对比
-
面向过程编程是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的;
-
面向对象是一种以对象为中心的编程思想,通过指挥对象实现具体的功能
-
面向对象思想小结:
- 客观存在的任何一种事务,都可以看作为程序中的对象
- 使用面向对象思想可以将复杂的问题简单化
- 将我们从执行者的位置,变成了指挥者
类和对象
- 类是对现实生活中一类具有共同属性和行为的事物的抽象
- 属性:该事物的各种特征
- 行为:该事物存在的功能(能够做的事情)
类和对象的关系
类:是对现实生活中一类具有共同属性和行为的事物的抽象
对象:对象是能够看得到摸得着的真实存在的实体
类是对象的描述,对象是类的实体
类的定义
类的组成:属性和行为
- 属性在代码中通过成员变量来实现(类中方法外的变量)
- 行为在代码中通过成员方法来实现(和前面的方法相比去掉static关键字即可)
public class 类名{
//成员变量
变量1的数据类型 变量1;
变量2的数据类型 变量2;
...
//成员方法
方法1;
方法2;
...
}
范例:
public class Student{
//属性:姓名,年龄
//成员变量:跟之前定义变量的格式一样,只不过位置发生了改变,类中方法外
String name;
int age;
//行为:学习
//成员方法:跟之前定义方法的格式一样,只不过去掉了static关键字
public void study(){
System.out.println("学习");
}
}
对象的使用
创建对象
- 格式:类名 对象名 = new 类名();
- 范例:Student s = new Student();
使用对象
- 使用成员变量
- 格式:对象名.变量名
- 范例:s.name
- 使用成员方法
- 格式:对象名.方法名()
- 范例:s.study();
案例
public class Phone {
//定义品牌、价格
String brand;
double price;
//打电话、发短信
public void call(String name){
System.out.println("给"+name+"打电话");
}
public void sendMessage(){
System.out.println("群发短信");
}
}
测试类:
public class TestPhone {
public static void main(String[] args) {
//创建对象
Phone p = new Phone();
//给成员变量进行赋值
p.brand = "华为";
p.price = 4129.99;
//打印赋值后的成员变量
System.out.println(p.brand+"......"+p.price);
//调用方法
p.call("阿花");
p.sendMessage();
}
}
结果:
补充:
-
创建一个对象,就会在内存(堆)中为其开辟一个空间,打印对象名时打印的就是对象的地址;
-
对象中属性在创建时都会有默认值;
-
当有多个对象时,每个对象的变量是各自的,但方法是相通的;
-
两个引用指向同一对象内存,只要一方修改了对象内存中的变量,两方看到的都是修改后的结果;
-
当堆内存中,对象或数组产生的地址,通过任何方式都不能被找到后,就会被判定为内存中的垃圾,垃圾会被java垃圾回收器在空闲的时候自动进行清理。
成员变量和局部变量
-
成员变量:类中方法外的变量
-
局部变量:方法中的变量
-
区别:
封装
-
private关键字
- private是一个权限修饰符,可以用来修饰成员(变量,方法)
- 特点:
- 只能在本类当中进行访问
-
针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
- 提供"get变量名()"方法,用于获取成员变量的值,方法用public修饰
- 提供"set变量名(参数)"方法,用于设置成员变量的值,方法用public修饰
-
private关键字的使用
- 一个标准的编写:
- 把成员变量用private修饰
- 提供对应的setXxx()/getXxx()方法
- 一个标准的编写:
-
this关键字
局部变量和成员变量如果重名,Java使用的就是就近原则;
- this关键字的作用:可以调用本类成员(变量,方法),解决局部变量和成员变量的重名问题
- this:代表所在类的对象引用;方法被哪个对象调用,this就代表哪个对象;
-
封装
- 面向对象三大特征之一(封装,继承,多态)
- 隐藏实现细节,仅对外暴露公共的访问方式
- 私有仅仅是封装的一种体现
- 将代码抽取到方法中,这是对代码的一种封装
- 将属性抽取到类当中,这是对数据的一种封装
-
封装的好处
- 提高了代码的安全性
- 提高了代码的复用性
构造方法
概述:
构建、创建对象的时候,所调用的方法;
格式:
- 方法名与类名相同,大小写也要一致
- 没有返回值的类型,连void都没有
- 没有具体的返回值(不能由return带回结果数据)
执行时机:
- 创建对象的时候调用,每创建在一次对象,就会执行一次构造方法
- 不能手动调用构造方法
构造方法作用及注意事项
- 用于给对象的数据(属性)进行初始化
- 注意事项
- 构造方法的创建
- 如果没有定义构造方法,系统将给出一个默认的无参数构造方法
- 如果定义了构造方法,系统将不再提供默认的构造方法
- 构造方法的重载
- 如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法
- 推荐使用的方式
- 无论是否使用,都手动书写无参构造方法和带参数构造方法
- 构造方法的创建
练习1
实现从控制台接收一个学员信息,并存储到一个对象中,打印这个对象的所有属性;
要求描述:定义一个学员类:Student,要求有以下属性:学员编号(Stirng)、姓名(String)、性别(String)、身高(double)、年龄(int),使用封装的原则,并提供无参和全参构造方法。定义MainAPP类,并包含main()方法;程序启动后,应分别提示用户输入信息。
Student类:
public class Student {
//定义类的属性
private String number;
private String name;
private String gender;
private double heigh;
private int age;
//无参构造方法
public Student() {
}
//全参构造方法
public Student(String number, String name, String gender, double heigh, int age) {
this.number = number;
this.name = name;
this.gender = gender;
this.heigh = heigh;
this.age = age;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getHeigh() {
return heigh;
}
public void setHeigh(double heigh) {
this.heigh = heigh;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//定义show方法,用于输出学员信息
public void show(){
System.out.println(gender+"学员"+name+"的编号为"+number+",其身高是"+heigh+"米,年龄是"+age+"岁。");
}
}
测试类MainAPP:
import java.util.Scanner;
public class MainApp {
public static void main(String[] args) {
//创建一个学员对象
Student s = new Student();
//通过键盘录入,依次为对象中的属性赋值
Scanner sc = new Scanner(System.in);
System.out.print("请输入学员编号:");
s.setNumber(sc.next());
System.out.print("请输入学员姓名:");
s.setName(sc.next());
System.out.print("请输入学员性别:");
s.setGender(sc.next());
System.out.print("请输入学员身高(单位:米):");
s.setHeigh(sc.nextDouble());
System.out.print("请输入学员年龄:");
s.setAge(sc.nextInt());
//调用方法,展示该对象的属性值
s.show();
}
}
运行结果:
练习2
分析以下需求,用代码实现:
1.项目经理类Manager,属性:姓名name、工号id、工资salary、奖金bonus;行为:工作work();
2.程序员类Coder,属性:姓名name、工号id、工资salary;行为:工作work();
要求:
1.按照要求定义Manager类和Coder类,属性要私有,输出、生成空参、有参构造方法,setter和geter方法
2.定义测试类,在main方法中创建该类的对象并给属性赋值(演示两种方法:setter方法和构造方法)
3.调用成员方法,打印格式如下:
工号为XXXXXX基本工资为XXX奖金为XXX的项目经理XXX正在努力的做着管理工作,分配任务,检查员工提交上来的代码…
工号为XXXX基本工资为XXX的程序员XXX正在努力的写着代码…
manager类
public class Manager {
private String name;
private String id;
private int salary;
private int bonus;
public void work(){
System.out.println("工号为"+id+"基本工资为"+salary+"奖金为"+bonus+"的" + "项目经理"+name+"正在努力做着管理工作,分配任务,检查员工提交上来的代码...");
}
//无参构造方法
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;
}
}
Coder类
public class Coder {
private String name;
private String id;
private int salary;
public void work(){
System.out.println("工号为"+id+"基本工资为"+salary+"的程序员"+name+"正在努力的写着代码...");
}
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 class WorkerTest {
public static void main(String[] args) {
//创建manager对象并初始化
Manager m = new Manager("小杰","A201112320",12000,8000);
//创建Coder对象
Coder c = new Coder();
//利用Coder方法给Coder对象中的属性初始化
c.setName("小龙");
c.setId("A201120531");
c.setSalary(10000);
//调用Manager中的work方法
m.work();
System.out.println();
//调用Coder中的work方法
c.work();
}
}
运行结果:
练习3
分析以下需求,并用代码实现,1.猫类Cat,属性:毛的颜色color,品种breed;行为:吃饭:eat(),抓老鼠catchMouse();2.狗类Dog,属性:毛的颜色color,品种breed;行为:吃饭eat(),看家lookHome().要求:
1.按照以上要求定义Cat类和Dog类,属性要私有,生成空参、有参构造,setter和getter方法
2.定义测试类,在main方法中创建该类的对象并给属性赋值(演示两种方法:setter方法和构造方法)
3.调用成员方法,测试代码效果
打印格式如下:
花色的波斯猫正在吃鱼…
蓝色的英国短毛猫正在逮老鼠…
棕色的泰迪正在啃骨头…
黑色的藏獒正在看家…
Cat类:
public class Cat {
private String color;
private String breed;
public void eat(){
System.out.println(color+"的"+breed+"正在吃鱼。");
}
public void catchMouse(){
System.out.println(color+"的"+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;
}
}
Dog类:
public class Dog {
private String color;
private String breed;
public void eat(){
System.out.println(color+"的"+breed+"正在啃骨头。");
}
public void lookHome(){
System.out.println(color+"的"+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 class Animal {
public static void main(String[] args) {
Cat c1 = new Cat("白色","美短猫");
c1.eat();
Cat c2 = new Cat();
c2.setColor("橘色");
c2.setBreed("橘猫");
c2.catchMouse();
Dog d1 = new Dog("黄色","拉布拉多犬");
d1.lookHome();
Dog d2 = new Dog();
d2.setColor("棕色");
d2.setBreed("泰迪");
d2.eat();
}
}
运行结果:
练习4
请设计一个汽车类,模拟出司机开车载乘客兜风的场景;在测试类中分别使用空参数构造方法创建对象和带参数构造方法创建对象并调用run方法,测试效果;
要求:
-
汽车类包含的成员变量:品牌、价格、颜色
-
汽车类包含的成员方法:getter/setter方法; run方法,有字符串类型的司机和乘客两个形参,无返回值
-
有带参数构造方法和空参数构造方法
Car类:
public class Car {
private String brand;
private double price;
private String color;
public void run(String siji,String chengke){
System.out.println(siji+"开着"+price+"万"+color+"的"+brand+"带着"+chengke+"去兜风。");
}
public Car() {
}
public Car(String brand, double price, String color) {
this.brand = brand;
this.price = price;
this.color = color;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
测试类:
public class CarTest {
public static void main(String[] args) {
Car c1 = new Car("捷豹",60,"灰色");
c1.run("杨过","小龙女");
Car c2 = new Car();
c2.setBrand("大众");
c2.setPrice(21);
c2.setColor("黑色");
c2.run("坤坤","战战");
}
}
运行结果: