初识面向对象
1. 万物皆对象
自然界中的任何事物 都可以通过分析其特征和行为 将其描述为对象
2. 属性和方法
一类事物共有的特征 使用属性描述
一类事物共有的行为 使用方法描述
3. 类和对象的关系
类是对象的抽象 对象是类的具体
4. 创建和使用对象
package com.atguigu.test5;
/**
* @author WHD
* @description TODO
* @date 2023/3/10 16:47
* 学生类
* (实例变量)属性:姓名 年龄 身高 体重 性别 爱好 家庭住址 ……
* (行为)方法:学习 吃饭 睡觉 敲代码 唱跳RAP 篮球
*/
public class Student {
String name;
int age;
double height;
public void study(){
System.out.println("学生学习");
}
public static void main(String[] args) {
// 第一步 创建对象 格式: 类名 对象名 = new 类名();
Student stu1 = new Student();
// 第二步 给对象赋值 格式 : 对象名.属性名 = 值;
stu1.name = "赵四";
stu1.age = 20;
stu1.height = 180.5;
// 第三步 访问对象的行为 方法 格式:对象名.方法名();
stu1.study();
}
}
5. 局部变量和实例变量
特征---->属性 、字段 Filed、实例变量 、成员变量
描述 | 局部变量 | 实例变量 |
---|---|---|
存储位置 | 基本数据类型存在栈中,引用数据类型,名字在栈,值在堆 | 实例变量 全部存在堆中 因为对象存在堆中 而实例变量依托与对象而存在 |
生命周期 | 随着方法的入栈而生效 随着方法的出栈而死亡 | 随着对象的创建而生效 随着对象被垃圾收集器回收而死亡 |
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2023/3/10 16:47
* 学生类
* (实例变量)属性:姓名 年龄 身高 体重 性别 爱好 家庭住址 ……
* (行为)方法:学习 吃饭 睡觉 敲代码 唱跳RAP 篮球
*
*
* 类相当于是一个模板
* 1.类中的属性和行为 将约束/规范到此类的每个对象 即此类的对象都将按照本类中书写 拥有固定的属性 和行为
* 2.模板是可以反复使用的
*
*
* 特征---->属性 、字段 Filed、实例变量 、成员变量
*
* 实例变量的特点:
* 定义位置:直接书写在类中
* 作用范围:整个类中
* 是否可以重名:可以与局部变量重名 局部变量优先使用(就近原则)
* 默认值:有默认值 与数组相同
*
* 存储位置:实例变量 全部存在堆中 因为对象存在堆中 而实例变量依托与对象而存在
* 生命周期:随着对象的创建而生效 随着对象被垃圾收集器回收而死亡
*
*
*/
public class Student {
String name;
int age;
double height;
public void study(){
// String name = "hello world";
System.out.println(name + "学生在学习");
}
public void printInfo(){
System.out.println("我的名字是:" + name);
System.out.println("我的年龄是:" + age);
System.out.println("我的身高是:" + height);
}
public static void main(String[] args) {
// 第一步 创建对象 格式: 类名 对象名 = new 类名();
Student stu1 = new Student();
// 第二步 给对象赋值 格式 : 对象名.属性名 = 值;
stu1.name = "赵四";
stu1.age = 20;
stu1.height = 180.5;
// 第三步 访问对象的行为 方法 格式:对象名.方法名();
stu1.study();
stu1.printInfo();
System.out.println("-----------------------------------------------");
Student stu2 = new Student();
stu2.name = "广坤";
stu2.age = 19;
stu2.height = 185;
stu2.study();
stu2.printInfo();
System.out.println("-----------------------------------------------");
Student stu3 = new Student();
stu3.name = "大拿";
stu3.age = 29;
stu3.height = 175;
stu3.study();
stu3.printInfo();
System.out.println("-----------------------------------------------");
Student stu4 = new Student();
stu4.name = "刘能";
stu4.printInfo();
}
}
6.课堂案例
老师类
属性:名字 专业 课程 教龄
行为:授课
f : field 字段
m :method 方法
关于静态方法和普通方法书写 以及使用的小细节
1.静态方法必须使用static修饰 而不同方法则不能使用static修饰
2.静态方法直接书写方法名调用 而普通方法必须创建对象 然后通过对象名加点调用
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 9:48
* 老师类
* 属性:名字 专业 课程 教龄
* 行为:授课
*
* f : field 字段
* m :method 方法
*
* 关于静态方法和普通方法书写 以及使用的小细节
* 1.静态方法必须使用static修饰 而不同方法则不能使用static修饰
* 2.静态方法直接书写方法名调用 而普通方法必须创建对象 然后通过对象名加点调用
*/
public class Teacher {
String name;
String profession;
String course;
int teachYear;
public void teach(){
System.out.println("老师授课,课程为:" + course);
}
public void printInfo(){
System.out.println("老师的名字为:" + name + ",专业为:" + profession + ",课程为:" + course + "教龄为:" + teachYear);
}
public static void main(String[] args) {
Teacher th1 = new Teacher();
th1.name = "赵四";
th1.course = "街舞";
th1.profession = "形体艺术";
th1.teachYear = 10;
th1.teach();
th1.printInfo();
Teacher th2 = new Teacher();
th2.teach();
th2.printInfo();
}
}
7. 构造方法和构造方法重载
构造方法:用于创建对象的特殊方法
构造方法格式 : 访问修饰符 + 类名(){}
普通方法格式: 访问修饰符 + 返回值类型 + 方法名(){}
无参构造: 如果没有书写无参构造 编译器默认提供
如果书写了有参构造方法 默认提供的无参构造将被覆盖 如需使用 则必须显式书写无参构造
构造方法的调用:不能手动调用 创建对象的同时即触发构造方法的调用
有参构造方法: 我们使用有参构造方法解决什么问题?
我们使用有参构造方法可以在创建对象的同时 给属性赋值
构造方法重载:同一个类中的构造方法 形参列表(个数、类型、顺序)不同 跟访问修饰符无关
package com.atguigu.test2;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 10:42
* 人类
* 属性: 名字 年龄 身高 体重 地址 性别
* 方法:吃饭 睡觉 学习 谈恋爱
*
*
* 构造方法:用于创建对象的特殊方法
* 构造方法格式 : 访问修饰符 + 类名(){}
* 普通方法格式: 访问修饰符 + 返回值类型 + 方法名(){}
*
* 无参构造: 如果没有书写无参构造 编译器默认提供
* 如果书写了有参构造方法 默认提供的无参构造将被覆盖 如需使用 则必须显式书写无参构造
*
* 构造方法的调用:不能手动调用 创建对象的同时即触发构造方法的调用
*
* 有参构造方法: 我们使用有参构造方法解决什么问题?
* 我们使用有参构造方法可以在创建对象的同时 给属性赋值
*
* 构造方法重载:同一个类中的构造方法 形参列表(个数、类型、顺序)不同 跟访问修饰符无关
*
*/
public class Person {
String name;
int age;
double height;
double weight;
String address;
char sex;
public void eat(){
System.out.println("人在吃饭");
}
public void study(){
System.out.println("人在学习");
}
public void love(){
System.out.println("谈恋爱");
}
public void print(){
System.out.println("我的名字是:" + name);
System.out.println("我的年龄是:" + age);
System.out.println("我的身高是:" + height);
System.out.println("我的体重是:" + weight);
System.out.println("我的地址是:" + address);
System.out.println("我的性别是:" + sex);
}
public Person(){
System.out.println("Person class 无参构造执行了");
}
public Person(String n,int a,double h,double w,String add,char s){
name = n;
age = a;
height = h;
weight = w;
address = add;
sex = s;
}
public Person(String n){
name = n;
}
public Person(String n,int a){
name = n;
age = a;
}
public static void main(String[] args) {
Person p1 = new Person();
p1.print();
System.out.println("-----------------------------------------------");
Person p2 = new Person("赵四", 20, 188, 70, "象牙山", '男');
p2.print();
System.out.println("-----------------------------------------------");
Person p3 = new Person("广坤");
p3.age = 20;
p3.address = "象牙山";
p3.height = 177;
p3.weight = 65;
p3.sex = '男';
p3.print();
System.out.println("-----------------------------------------------");
Person p4 = new Person("大拿", 25);
p4.print();
}
}
8.this关键字
this关键字:this指向当前对象 当前创建的哪个对象 就指向哪个对象
单词:这个
适用场景:可以用于访问属性 、 方法 、 构造方法
8.1 this访问属性
在之前的案例中,我们编写的有参构造方法的形参,命名是不规范的 ,所以我们应该修改参数命名,修改以后就出现了形参名称和实例变量名称相同的问题,我们可以使用this关键解决这个问题
package com.atguigu.test3;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 10:42
* 人类
* 属性: 名字 年龄 身高 体重 地址 性别
* 方法:吃饭 睡觉 学习 谈恋爱
*
* this关键字:this指向当前对象 当前创建的哪个对象 就指向哪个对象
* 单词:这个
* 适用场景:可以用于访问属性 、 方法 、 构造方法
*
*
* 我们在创建对象的时候 一定会触发某个构造方法的调用 但是 调用构造方法 并不一定创建对象
*
* 关于this访问构造方法
* this访问本类的构造方法 必须在构造方法中的第一句
*
* 关于构造方法书写:在实际开发中 我们通常只需要书写两个构造方法 即可满足90%的开发场景
* 一个无参 一个全参
*
*/
public class Person {
String name;
int age;
double height;
double weight;
String address;
char sex;
public Person(String name, int age, double height, double weight, String address, char sex){
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
this.address = address;
this.sex = sex;
}
public static void main(String[] args) {
Person p2 = new Person("赵四", 20, 188, 70, "象牙山", '男');
}
}
8.2 this访问方法
this关键字也可以访问本类中的普通方法,直接使用this.方法名即可
访问本类方法的目的在于提高代码的重用性
package com.atguigu.test3;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 10:42
* 人类
* 属性: 名字 年龄 身高 体重 地址 性别
* 方法:吃饭 睡觉 学习 谈恋爱
*
* this关键字:this指向当前对象 当前创建的哪个对象 就指向哪个对象
* 单词:这个
* 适用场景:可以用于访问属性 、 方法 、 构造方法
*
*
* 我们在创建对象的时候 一定会触发某个构造方法的调用 但是 调用构造方法 并不一定创建对象
*
* 关于this访问构造方法
* this访问本类的构造方法 必须在构造方法中的第一句
*
* 关于构造方法书写:在实际开发中 我们通常只需要书写两个构造方法 即可满足90%的开发场景
* 一个无参 一个全参
*
*/
public class Person {
String name;
int age;
double height;
double weight;
String address;
char sex;
public void printName(){
System.out.println("我的名字是:" + name);
}
public void printAge(){
System.out.println("我的年龄是:" + age);
}
public void print(){
printName(); // 普通方法之间可以使用this关键字互相调用 也可以直接书写方法名调用
this.printAge();
System.out.println("我的身高是:" + height);
System.out.println("我的体重是:" + weight);
System.out.println("我的地址是:" + address);
System.out.println("我的性别是:" + sex);
}
}
8.3 this访问构造方法
关于this访问构造方法
this访问本类的构造方法 必须在构造方法中的第一句
package com.atguigu.test3;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 10:42
* 人类
* 属性: 名字 年龄 身高 体重 地址 性别
* 方法:吃饭 睡觉 学习 谈恋爱
*
* this关键字:this指向当前对象 当前创建的哪个对象 就指向哪个对象
* 单词:这个
* 适用场景:可以用于访问属性 、 方法 、 构造方法
*
*
* 我们在创建对象的时候 一定会触发某个构造方法的调用 但是 调用构造方法 并不一定创建对象
*
* 关于this访问构造方法
* this访问本类的构造方法 必须在构造方法中的第一句
*
* 关于构造方法书写:在实际开发中 我们通常只需要书写两个构造方法 即可满足90%的开发场景
* 一个无参 一个全参
*
*/
public class Person {
String name;
int age;
double height;
double weight;
String address;
char sex;
public Person(){
System.out.println("Person class 无参构造执行了");
}
public Person(String name){
this.name = name;
}
public Person(int age){
this.age = age;
}
public Person(String name, int age){
this(name);
this.age = age;
}
public Person(int age,String name ){
this(name);
this.age = age;
}
public Person(String name, int age, double height, double weight, String address, char sex){
this(name,age);
this.height = height;
this.weight = weight;
this.address = address;
this.sex = sex;
}
public static void main(String[] args) {
Person p2 = new Person("赵四", 20, 188, 70, "象牙山", '男');
p2.print();
System.out.println("--------------------------------------");
Person p3 = new Person("大拿",20);
}
}
9. 关于构造方法补充
- 我们在创建对象的时候 一定会触发某个构造方法的调用 但是 调用构造方法 并不一定创建对象
- 在实际开发中 我们通常只需要书写两个构造方法 即可满足90%的开发场景:一个无参 一个全参
10. 封装
封装:将类的信息隐藏在类的内部 不让外部程序直接访问 而是提供便捷的接口 供外界访问
属性私有 :将所有的属性使用private修饰 实现隐藏
private关键字:访问权限修饰符之一 被private修饰的内容 只能在本类中访问
方法公开 :针对每个属性编写一对公开的方法 用于给外界访问 分别为 getter 以及 setter方法
get方法用于获取属性值 必须有返回值 没有参数 相当于 取值
set方法用于设置属性值 必须有参数 没有返回值 相当于 存值
package com.atguigu.test4;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 14:48
* 企鹅类
* 属性:名字 健康值 性别
*
* 封装:将类的信息隐藏在类的内部 不让外部程序直接访问 而是提供便捷的接口 供外界访问
*
* 属性私有 :将所有的属性使用private修饰 实现隐藏
* private关键字:访问权限修饰符之一 被private修饰的内容 只能在本类中访问
*
* 方法公开 :针对每个属性编写一对公开的方法 用于给外界访问 分别为 getter 以及 setter方法
* get方法用于获取属性值 必须有返回值 没有参数 相当于 取值
* set方法用于设置属性值 必须有参数 没有返回值 相当于 存值
*
* 高内聚 :一个类中所描述信息(属性和方法)应该直接与本类产生关联关系 不能间接关联或者 没有关联
* 低耦合 : 耦合度即程序各个组件之间的紧密连接程度 更低的耦合度有利于提高程序的灵活性 可扩展性 可维护性
*
*/
public class Penguin {
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
private int health;
// set方法需要对数据做校验 而get方则直接获取值即可 不需要做校验
// 因为我们只需要把控好入口 出口无需关注
// 关于this访问属性 不是必须 除非局部变量与实例变量重名
public void setHealth(int health){
if(health >= 0 && health <= 100){
this.health = health;
}else{
System.out.println("健康值赋值不合理,将使用默认健康值:60");
this.health = 60;
}
}
public int getHealth(){
return health;
}
private String sex;
public void setSex(String sex){
if(sex.equals("雌") || sex.equals("雄")){
this.sex = sex;
}else{
System.out.println("性别不赋值不合理,将使用默认性别:雄");
this.sex = "雄";
}
}
public String getSex(){
return sex;
}
}
package com.atguigu.test4;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 14:56
* 企鹅测试类
*/
public class TestPenguin {
public static void main(String[] args) {
Penguin p2 = new Penguin();
// p2.name = "大白";
// p2.health = -250;
// p2.sex = "雌性";
p2.setName("大白");
p2.setHealth(-250);
p2.setSex("男");
// System.out.println(p2.name);
// System.out.println(p2.health);
// System.out.println(p2.sex);
System.out.println(p2.getName());
System.out.println(p2.getHealth());
System.out.println(p2.getSex());
}
}
11. 封装的好处
便于使用者正确使用系统,防止错误修改属性
降低了构建大型系统的风险
提高程序的可重用性
降低程序之间的耦合度
12. 高内聚和低耦合
高内聚 :一个类中所描述信息(属性和方法)应该直接与本类产生关联关系 不能间接关联或者 没有关联
低耦合 : 耦合度即程序各个组件之间的紧密连接程度 更低的耦合度有利于提高程序的灵活性 可扩展性 可维护性
13. 访问权限修饰符
13.1 类的访问权限修饰符
类的访问权限修饰符
public : 本项目中任何位置都可以访问
默认不写:表示包级别的访问权限 即只能在同包中可以访问
13.2 类成员的访问权限修饰符
13.3 关于同名类的访问
如果需要在一个类中同时访问两个同名但是不同包的类,可以使用全限定名加以区分
package com.atguigu.test10;
import com.atguigu.test8.D;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 16:28
*/
public class TestD {
public static void main(String[] args) {
D d1 = new D();
com.atguigu.test9.D d2 = new com.atguigu.test9.D();
}
}
14 值传递和引用传递的区别?
值传递和引用传递的区别?
基本数据类型传参属于值传递 传递的是值的副本 值的拷贝 在方法中对值的改变不会影响原变量
引用数据类型传参属于引用传递 传递的是地址 在方法中对参数的改变会影响原变量
String类型属于特殊的引用数据类型 作为参数传递不会改变原变量
Java官方明确指出 Java中只有值传递 '引用传递'也属于值传递 只不过这个值是一个地址
package com.atguigu.test11;
import java.util.Arrays;
/**
* @author WHD
* @description TODO
* @date 2023/3/11 16:34
* 值传递和引用传递的区别?
* 基本数据类型传参属于值传递 传递的是值的副本 值的拷贝 在方法中对值的改变不会影响原变量
* 引用数据类型传参属于引用传递 传递的是地址 在方法中对参数的改变会影响原变量
* String类型属于特殊的引用数据类型 作为参数传递不会改变原变量
*
* Java官方明确指出 Java中只有值传递 '引用传递'也属于值传递 只不过这个值是一个地址
*
*/
public class TestParameter {
public static void m1(int num){
num += 10;
}
public static void m2(int [] nums){
for(int i = 0;i < nums.length;i++){
nums[i]++;
}
}
public static void m3(String str){
str += "abc";
}
public static void main(String[] args) {
int a = 10;
m1(a);
System.out.println(a); // 10
int [] b = {1,2,3,4,5};
m2(b);
System.out.println(Arrays.toString(b));
String c = "hello";
m3(c);
System.out.println(c);
}
}
标签:name,构造方法,对象,面对,println,out,public,初始,String
From: https://www.cnblogs.com/MindHunter/p/17460717.html