08-面向对象
1、设计对象并使用
类和对象
类(设计图):对象共同特性的描述
对象:真实存在的具体东西
在Java中,必须先设计类,才能获得对象
class 定义类
调用class 定义对象
调用生成的对象:
对象.成员变量;
对象.成员方法(...)// 定义类
public class 类名 {
1、成员变量(代表属性,一般是名词)
2、成员方法(代表行为,一般是动词)
3、构造器
4、代码块
5、内部类
}
public class Phone {
//属性(成员变量)
String brand;
double price;
//行为(方法)
public void call(){
}
public void playGame(){
}
}
//得到类的对象
// 类名 对象名 = new 类名();
// Phone p = new Phone();
public class Phone {
//属性
String brand;
double price;
//行为
public void call(){
System.out.println("手机在打电话");
}
public void playGame(){
System.out.println("手机在玩游戏");
}
}
public class PhoneTest{
public static void main(String[] args){
//创建手机的对象
Phone p = new Phone();
//给手机赋值变量
p.brand = "小米";
p.price = 1999.98;
//获取手机对象中的值
System.out.println(p.brand);
System.out.println(p.price);
//调用手机中的方法
p.call();
p.playGame();
Phone p2 = new Phone();
p2.brand = "苹果";
p2.price = 8999;
p2.call();
p2.playGame();
}
}定义类的注意事项:
1.用来描述一类事物的类,叫做Javabean类(在Javabean类中,不写main方法)
2.之前编写main方法的类,叫做测试类(可以在测试类中创建Javabean类的对象并进行赋值调用)
3.类名建议首字母大写,需见名知意,驼峰模式
4.一个Java文件一颗定义多个class类(但是智能一个类是public修饰的),建议一个文件定义一个class类
public修饰的类名必须是Java代码的文件名
5.成员变量的完整定义格式: 修饰符 数据类型 变量名称 = 初始化值
(一般无需指定初始化值,默认存在)
对象的成员变量默认规则:
基本数据类型:
byte、short、int、long --》默认值 0
float、double --》默认值 0.0
boolean --》默认值 false
引用数据类型:
类、接口、数组、String --》默认值 null开发中类的设计
名词提炼法2、封装
面向对象变成的三大特性:封装、继承、多态
封装:正确设计对象的属性和方法
对象代表什么,就得封装对应的数据,并提供数据对应的行为
// 需求:人画圆,请针对整个需求进行面向对象设计
public class Circel {
double redius;
public void draw(){
System.out.println("根据半径" + redius + "画一个圆");
}
}
// 人关门
public class Door {
boolean flag = true; // 门的状态数据
public void open(){
//开门,修改门的状态
}
public void close(){
//开门,修改门的状态
}
}/*
private关键字:(保证数据的安全性)
1、是一个权限修饰符
2、可以修饰成员(成员变量和成员方法)
3、被private修饰的成员智能在本类中才访问
*/
// =============GirlFriend.java===================
public com.yq.test3;
public class GirlFriend{
//属性
private String name;
private int age;
private String gender;
//setName给name赋值,getName获取
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
//setAge给age赋值,getAge获取
public void setName(int a){
if(a >= 18 && a <= 50){
age = a;
} else {
System.out.println("非法参数");
}
}
public String getAge(){
return age;
}
//gender
public void setGender(String g){
gender = g;
}
public String getGender(){
return gender;
}
//行为
public void sleep(){
System.out.println("女朋友在睡觉");
}
public void eat(){
System.out.println("女朋友在吃饭");
}
}
// =============GirlFriendTest.java===================
package com.yq.test3;
public class GirlFriendTest {
public static void main(String[] args){
//创建女朋友的对象
// 赋值并调用方法
GirlFriend gf1 = new GirlFriend();
gf1.setName(小诗诗);
gf1.setAge(18);
gf1.setGender(萌妹子);
System.out.println(gf1.getName());
System.out.println(gf1.getAge());
System.out.println(gf1.getGender());
gf1.eat();
gf1.sleep();
}
}
3、this关键字
就近原则:谁离得近,就用谁
this的作用:区分成员变量和局部变量
// ======================test4/GirlFriend.java=================
package com.yq.test4;
public class GirlFriend {
private int age;
public void method(){
int age = 10;
System.out.println(age); //如果没有this,触发就近原则,谁近用谁
System.out.println(this.age); //使用成员变量,默认值
}
}
// ======================test4/GirlFriendTest.java=================
package com.yq.test4;
public class GirlFriendTest{
public static void main(String[] args){
GirlFriend gf1 = new GirlFriend();
gf1.method();
}
}
// ======================test3/GirlFriend.java=================
package com.yq.test3;
public class GirlFriend{
//属性
private String name;
private int age;
private String gender;
//setName给name赋值,getName获取
public void setName(String name){
this.name = name; //调用方法传递进来的name,赋值给成员变量name(private属性)
}
public String getName(){
return name;
}
//setAge给age赋值,getAge获取
public void setAge(int age){
if(age >= 18 && age <= 50){
this.age = age; //调用方法传递进来的age,赋值给成员变量age(private属性)
} else {
System.out.println("非法参数");
}
}
public int getAge(){
return age;
}
//gender
public void setGender(String gender){
this.gender = gender; //调用方法传递进来的gender,赋值给成员变量gender(private属性)
}
public String getGender(){
return gender;
}
//行为
public void sleep(){
System.out.println("女朋友在睡觉");
}
public void eat(){
System.out.println("女朋友在吃饭");
}
}
// ======================test3/GirlFriendTest.java=================
package com.yq.test3;
public class GirlFriendTest {
public static void main(String[] args){
//创建女朋友的对象
// 赋值并调用方法
GirlFriend gf1 = new GirlFriend();
gf1.setName("小诗诗");
gf1.setAge(18);
gf1.setGender("萌妹子");
System.out.println(gf1.getName());
System.out.println(gf1.getAge());
System.out.println(gf1.getGender());
gf1.eat();
gf1.sleep();
}
}4、构造方法
构造方法:在创建对象时,给成员变量进行赋值
// 构造方法的格式
public class Student {
修饰符 类名(参数) {
方法体;
}
}
/*
特点:
1、方法名与类名相同,大小写也要一致
2、没有返回值类型,连void都没有
3、没有具体的返回值(不能由return带回结果数据)
执行时机:
1、创建对象时,由虚拟机调用,不能手动调用构造方法
2、每创建一次对象,就会调用一次构造方法
*/====================Student.java===============
package com.yq.test5;
public class Student {
private String name;
private int age;
// 如果我们自己没有写任何的构造方法
// 那么虚拟机会给我们加一个空参构造方法
public Student(){
System.out.println("看看我执行了吗?");
}
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;
}
}
====================StudentTest.java===============
package com.yq.test5;
public class StudentTest {
public static void main(String[] args){
// 创建对象
// 调用的空参构造
Student s = new Student();
Student s1 = new Student("zhangsan", 23);
System.out.println(s1.getName());
System.out.println(s1.getAge());
}
}构造方法注意事项:
1、构造方法的定义
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
若定义了带参构造方法,系统将不再提供默认的构造方法
2、构造方法的重载
带参构造方法、和无参数构造方法,两者方法名相同,但是参数不同。叫做构造方法的重载
3、推荐的使用方式
无论是否使用,都手动书写无参数构造方法,和带全部参数的构造方法
构造方法概述:
(构造方法就是用来创建对象的(说法不对))
创建对象时,虚拟机会自动调用构造方法,作用是给成员变量进行赋值5、标准JavaBean
1、类名需要见名知意
2、成员变量使用 private 修饰
3、提供至少两个构造方法
无参数构造方法
带全部参数的构造方法
4、成员方法
提供每一个成员变量对应的setXxx()/getXxx()
如果还有其他行为,也需要写上================User.java===============
package com.yq.test6;
public class User {
//属性
private String username;
private String password;
private String email;
private String gender;
private int age;
// 快捷键:alt + insert
// 插件:PTG 一秒生成JavaBean
//空参
public User(){}
//带全部参数的构造
public User(String username, String password, String email, String gender, int age){
this.username = username;
this.password = password;
this.email = email;
this.gender = gender;
this.age = age;
}
//get set 方法
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
public void setPassword(String password){
this.password = password;
}
public String getPassword(){
return password;
}
public void setEmail(String email){
this.email = email;
}
public String getEmail(){
return email;
}
public void setGender(String gender){
this.gender = gender;
}
public String getGender(){
return gender;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
================UserTest.java===============
package com.yq.test6;
public class UserTest {
public static void main(String[] args){
// 创建对象
// 调用的空参构造
User s = new User();
User s1 = new User("张三", "123456", "123@123.com", "男", 23);
System.out.println(s1.getUsername());
System.out.println(s1.getPassword());
System.out.println(s1.getEmail());
System.out.println(s1.getGender());
System.out.println(s1.getAge());
}
}6、对象内存图
Java内存分配:栈、堆、方法区
6.1 一个对象的内存图
Student s = new Student();
1.加载class文件
2.申明局部变量
3.在堆空间中开辟一个空间
4.默认初始化
5.显示初始化
6.构造方法初始化
7.将堆空间中的地址值赋值给左边的局部变量一个对象的内存图

6.2 多个对象的内存图
两个对象的内存图

总结:
多个对象在堆内存中,都有不同的内存划分,成员变量存储在各自的内存区域中,成员方法多个对象共用的一份
6.3 两个变量指向同一个对象的内存图
两个引用指向同一个对象

6.4 this的内存原理
this的作用:区分局部变量和成员变量
this的本质:所在方法调用者的地址值


6.5 基本数据类型和引用数据类型的区别
基本数据类型:变量中存储的是真实的数据值,赋值给其他变量,赋值的是真实的值
引用数据类型:变量中存储的是数据值指向的地址值,赋值给其他变量,赋值的是地址值
6.6 局部变量和成员变量的区别
/*
成员变量:类中方法外的变量
局部变量:方法中的变量
*/
public class Student{
String name; //name:成员变量
public void study(){
int i = 0; //局部变量
System.out.println("好好学习");
}
public void doHomework(){
System.out.println("多做练习");
int j = 0; //局部变量
}
int age; //age: 成员变量
}7、补充:成员变量、局部变量区别
详见 6.6
评论区