该文章Github地址:https://github.com/AntonyCheng/java-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】
在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!
上一章:由浅到深认识Java语言(9):Eclipse IDE简介
18.面向对象
面向对象简述
面向对象是高级程序设计语言的核心,是对现实世界的还原,也是目前市面上最主流的程序设计思想,要开发一定要搞清楚面向对象;
关键是:类 和 对象;
举例:把大象装进冰箱分几步?
-
面向过程:人打开冰箱,放进大象,关闭冰箱门;
main(){ 人打开冰箱,放进大象,关闭冰箱门; }
-
面向对象:
-
人:打开物体,关上物体;
-
冰箱:开门,关门;
-
大象:进入物体;
main(){ 人.去打开冰箱; 冰箱.开门; 大象.进入冰箱; 人.关上冰箱; 冰箱.关门; }
-
类和对象的关系
类是一种统称,例如一种类型,一种概念的描述;
例如:用编程语言描述一个人;
public class people{
int hand = 2;
int leg = 2;
//用方法描述功能
void sleep(){
System.out.println("睡觉!");
}
void eat(){
System.out.println("吃饭!");
}
}
对象是某一个类的实实在在的实例;
例如:张三是一个人!
则 “张三” 是对象,而 “人” 就是类;
总结:
类是模板,对象是根据模板创建出来的一个实实在在的个体;
补充:简述内存区域;
堆:new 出来的东西全部都放在堆里面;
Scanner scanner = new Scanner(System.in);
栈:局部变量存放的位置;
方法区:方法的引用,方法的权限,静态的变量,常量池等;
本地方法区:和系统相关的一些(native)原生方法,例如一些C语言的方法;
如何创建对象(构造器:类的第二成员)
基本格式:
类名 对象名 = new 类名();
其中“类名()”是类的构造器;
关键字 new:
作用是在内存的堆空间中开辟一块区域,该区域就是常见出来的具体对象存在的区域;
如何使用对象
对象在内存中的样子:
接下来要考虑的是程序如何执行,如何写;
而是考虑对象存不存在,对象里有哪些东西,有就可以用,没有就不能用;
方式一:使用对象的属性:
基本格式:
对象名.属性;
即使用对象的成员变量(定义在类的内部,方法的外部);
student类:
package top.sharehome.BagOne;
public class student {
String name = "张三";
char sex = '男';
void study(){
System.out.println("学海无涯苦作舟!");
}
void sleep() {
System.out.println("学累了,要睡觉!");
}
void exam() {
System.out.println("每天早上要考试!");
}
}
sharehome类:
package top.sharehome.BagOne;
public class sharehome {
public static void main(String[] args) {
//如何使用类来创建对象
student zhenzhangsan = new student();
//使用对象的属性
zhenzhangsan.name = "真张三";
//再次创建
student jiazhangsan = new student();
//再次使用对象的属性
jiazhangsan.name = "假张三";
System.out.println(zhenzhangsan.name);
System.out.println(jiazhangsan.name);
}
}
打印效果如下:
方式二:使用对象的方法:
基本格式:
对象名.方法;
student类:
package top.sharehome.BagOne;
public class student {
String name = "张三";
char sex = '男';
void study(){
System.out.println("学海无涯苦作舟!");
}
void sleep() {
System.out.println("学累了,要睡觉!");
}
void exam() {
System.out.println("每天早上要考试!");
}
}
sharehome类:
package top.sharehome.BagOne;
public class sharehome {
public static void main(String[] args) {
//如何使用类来创建对象
student zhenzhangsan = new student();
//使用对象的方法
zhenzhangsan.sleep();
//再次创建
student jiazhangsan = new student();
//再次使用对象的方法
jiazhangsan.study();
}
}
打印效果如下:
对象小结
Q : Q: Q: 如何使用面向对象的概念进行程序开发?
A
:
A:
A: 首先编写和设计类 <====> 重点是类的设计;
然后使用类来创建对象;
最后使用对象的属性和方法来满足实际场景的需要;
类小结
Q : Q: Q: 如何设计类?
A : A: A: 大体格式如下:(以下几个部分并不是都要出现)
类的五大成员:属性,方法,构造器,代码块,内部类
class 类名{
1.成员变量(属性)
2. 方法(){
}
3. 构造方法
4. 代码块 //静态代码块 static{} 构造代码块用 {}
5. class 类名{
} //内部类:class 类名{}
}
-
成员变量:
定义在类的内部,方法的外部;
成员变量和局部变量的区别:
定义位置不同 { 成员变量:定义在类中,方法外; 局部变量:定义在方法中或者方法声明上; \bf{定义位置不同}\begin{cases}\bf{成员变量:定义在类中,方法外;}\\\bf{局部变量:定义在方法中或者方法声明上;} \end{cases} 定义位置不同{成员变量:定义在类中,方法外;局部变量:定义在方法中或者方法声明上;生命周期不同 { 成员变量:随着对象的创建而存在,随着对象的消亡而消亡; 局部变量:随着方法的调用而存在,随着方法的结束而消亡; \bf{生命周期不同}\begin{cases}\bf{成员变量:随着对象的创建而存在,随着对象的消亡而消亡;}\\\bf{局部变量:随着方法的调用而存在,随着方法的结束而消亡;}\end{cases} 生命周期不同{成员变量:随着对象的创建而存在,随着对象的消亡而消亡;局部变量:随着方法的调用而存在,随着方法的结束而消亡;
内存中的位置不同 { 成员变量:在堆内存(成员变量属于对象,对象进堆内存) 局部变量:在栈内存(局部变量属于方法,方法进栈内存) \bf{内存中的位置不同}\begin{cases}\bf{成员变量:在堆内存(成员变量属于对象,对象进堆内存)}\\\bf{局部变量:在栈内存(局部变量属于方法,方法进栈内存)}\end{cases} 内存中的位置不同{成员变量:在堆内存(成员变量属于对象,对象进堆内存)局部变量:在栈内存(局部变量属于方法,方法进栈内存)
初始化值不同 { 成员变量:有默认值,是在对象创建的过程中 J V M 设置的默认值; 局部变量:没有默认值,必须在使用之前赋值; \bf{初始化值不同}\begin{cases}\bf{成员变量:有默认值,是在对象创建的过程中JVM设置的默认值;}\\\bf{局部变量:没有默认值,必须在使用之前赋值;} \end{cases} 初始化值不同{成员变量:有默认值,是在对象创建的过程中JVM设置的默认值;局部变量:没有默认值,必须在使用之前赋值;
注意事项:
- 局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则;
- 基本数据类型变量包括:byte , short , int , long , float , double , boolean , char;
- 引用数据类型变量包括:数组 ,类 ,接口 ,枚举 ;
-
构造方法/构造器(Constructor):构造器和方法不一样!!!
基本格式:
Constructor con = new Constructor();
这句代码正在创建对象,同时调用了指定的构造器;
package top.sharehome.BagOne; public class Cat { String name; int age; char sex; public Cat(String Name,int Age,char Sex) { //这是一个构造器 name = Name; age = Age; sex = Sex; } }
构造器的作用是在创建对象时,为对象属性做初始化工作(给对象的所有或部分属性赋初值);
示例如下:
Cat 类:
package top.sharehome.BagOne; public class Cat { String name; int age; char sex; public Cat(String Name,int Age,char Sex) { //这是一个构造器 name = Name; age = Age; sex = Sex; } }
Test 类:
package top.sharehome.BagOne; public class Test { public static void main(String[] args) { Cat cat = new Cat("小灰",2,'雄'); System.out.println(cat.name); System.out.println(cat.age); System.out.println(cat.sex); } }
打印效果如下:
构造器的创建:
面向对象的设计重点是类的设计,构造器是类的一部分,在类中设计构造器;
即:构造器不在主函数 java 文件中,而在类 java 文件中,且和类同名,同时不能有返回类型;
构造器的格式:
public class Method{ public Method(){ //这是一个构造器 } }
一个类可以有多个重载的构造器,这是为了方便创建对象时满足不同的要求:
Cat 类:
package top.sharehome.BagOne; public class Cat { String name; int age; char sex; public Cat() { } public Cat(String Name,int Age,char Sex) { name = Name; age = Age; sex = Sex; } public Cat(String Name) { name = Name; } public Cat(int Age) { age = Age; } public Cat(char Sex) { sex = Sex; } }
Test 类:
package top.sharehome.BagOne; import java.util.*; public class Test { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入家猫一项或全部的信息!"); System.out.println("你选择一项还是全部?(一项/全部==1/0)"); int select = sc.nextInt(); if (select == 1) { System.out.print("你想输入名字/年龄/性别中的哪一项?(名字/年龄/性别==1/2/3)"); int choice = sc.nextInt(); if(choice == 1) { System.out.print("请输入家猫名字:"); String Name = sc.next(); System.out.println(); System.out.print("你家家猫名字是:"); Cat c1 = new Cat(Name); System.out.println(c1.name); }else if(choice == 2) { System.out.print("请输入家猫年龄:"); int Age = sc.nextInt(); System.out.println(); System.out.print("你家家猫年龄是:"); Cat c1 = new Cat(Age); System.out.println(c1.age); }else if(choice == 3) { System.out.print("请输入家猫性别:"); char Sex = sc.next().charAt(0); System.out.println(); System.out.print("你家家猫性别是:"); Cat c1 = new Cat(Sex); System.out.println(c1.sex); }else { System.out.println("输入错误,请重新启动程序!"); } }else if(select == 0) { System.out.print("请输入家猫名字:"); String Name = sc.next(); System.out.println(); System.out.print("请输入家猫年龄:"); int Age = sc.nextInt(); System.out.println(); System.out.print("请输入家猫性别:"); char Sex = sc.next().charAt(0); System.out.println(); System.out.println("你家家猫的信息如下:"); Cat c2 = new Cat(Name,Age,Sex); System.out.println("你家家猫的名字是"+c2.name); System.out.println("你家家猫的年龄是"+c2.age); System.out.println("你家家猫的性别是"+c2.sex); }else { System.out.println("输入错误,请重新执行程序!"); } sc.close(); } }
打印效果如下:
注意:
- 如果一个类里面没有显式地定义任何构造器,那么 JVM 就会默认创建一个空参构造器;
- 如果一个类中显式地定义了任何一个构造器(带参或者空参),那么 JVM 就不会创建一个空参地构造器;
- 所以可以习惯性地手动创建一个空参构造器;
构造器的使用:
在创建对象时需要指明使用哪一个构造器,格式如下:
类 对象名 = new 类名(); //"类名()"就是构造器的调用
this关键字
this 可以修饰属性、方法和构造器,其实默认状态下,每个成员变量前都被 this 隐式修饰;
目前主要是为了打破局部优先;
等到学习继承时是为了打破父子关系;
this.name; //当前对象的属性
this.method(); //当前对象的方法
this 修饰属性:
package top.sharehome.BagOne;
public class Test {
String name; //这里的 name 标为 A.name
int age; //这里的 age 标为 A.age
public Test(String name,int age) {
this.name = name; //此时的 this.name = A.name
this.age = age; //此时的 this.age = A.age
}
}
this修饰方法:
package top.sharehome.BagOne;
public class Test {
void eat() {
System.out.println("吃饭");
this.sleep(); //也可以直接 sleep();
}
void sleep() {
System.out.println("睡觉");
}
}
this修饰构造器:
写代码时基本不会用到,但是看代码时经常会看到:
目的:让构造器复用;
注意:
- “
this(重载方法参数列表)
” 只能出现在构造器中且只能出现在首行; - 一个类中,如果有 n 个构造器,那么最多只能出现 n-1 个构造器,不然会进入死循环;
Test 类:
package top.sharehome.BagOne;
public class Test {
String name = null;
int age = 0;
char sex = '空';
public Test() {
this("小明",9); //调用Test(String name,int age)
System.out.println("Test()");
System.out.println(name+" "+age+" "+sex);
}
public Test(String name,int age) {
this("小红",10,'女'); //调用Test(String name,int age)
this.name = name;
this.age = age;
System.out.println("Test(String name,int age)");
System.out.println(name+" "+age+" "+sex);
}
public Test(String name,int age,char sex) {
this.name = name;
this.age = age;
this.sex = sex;
System.out.println("public Test(String name,int age,char sex)");
System.out.println(name+" "+age+" "+sex);
}
}
T 类:
package top.sharehome.BagOne;
public class T {
public static void main(String[] args) {
Test test = new Test();
}
}
打印效果如下:
实例展示
实例一:
定义人类的属性:姓名,年龄,性别;
定义人类的方法:工作,睡觉,自我介绍;
创建不同的人的实例对象,并调用方法,打印属性数据;
Person类:
package top.sharehome.BagOne;
public class Person {
String name;
int age;
char sex;
void work() {
System.out.println("工作");
}
void sleep() {
System.out.println("睡觉");
}
void self_info() {
System.out.println("自我介绍");
}
}
Test类:
package top.sharehome.BagOne;
public class Test {
public static void main(String[] args) {
Person chen = new Person();
chen.name = "陈一";
chen.age = 25;
chen.sex = '女';
System.out.print(chen.name+" ");
System.out.print(chen.age+" ");
System.out.print(chen.sex+" ");
System.out.println();
chen.work();
chen.sleep();
chen.self_info();
}
}
打印效果如下:
实例二:
新生入学,需要录入学生信息,编写程序,录入资料系统;
要求围绕此内容编程:定义学号为 年份+性别+年级+班级+编号(编号由每班人数决定);
Student 类:
package top.sharehome.BagOne;
public class Student {
String Name;
int Sex;
int Grade;
int Class;
int Age;
public Student(String n,int s,int g,int c,int a) {
Name = n;
Sex = s;
Grade = g;
Class = c;
Age = a;
}
}
TeachSystem 类:
package top.sharehome.BagOne;
import java.util.*;
public class TeachSystem {
public static void main(String[] args) {
// 定义学号为 出生年份+性别+年级+班级+编号(编号由每班人数决定)
Scanner sc = new Scanner(System.in);
System.out.println("输入班级号:(四班==4)");
int c = sc.nextInt();
System.out.println("请输入班级人数:");
int number = sc.nextInt();
String[] str = new String[number];
System.out.println("请输入班级所在年级:(2020级==2020)");
int g = sc.nextInt();
if (number < 0) {
System.out.println("输入错误,请重新启动程序!");
} else if (number == 0) {
System.out.println("该班不存在!");
} else {
for (int i = 0; i < number; i++) {
System.out.println("请输入第" + (i + 1) + "学生名字:");
String n = sc.next();
System.out.println("请输入该学生出生年份:");
int a = sc.nextInt();
System.out.println("请输入该学生性别:(男/女==1/0)");
int s = sc.nextInt();
Student Stu = new Student(n, s, g, c, a);
str[i] = "第"+(i+1)+"个叫"+n+" 学号为"+a+s+g+c+(i+1);
}
System.out.println("===================");
System.out.println("你的班级信息是");
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
sc.close();
}
}
打印效果如下: