目录

Chapter07 面向对象

目录

7.1 类与对象

  1. 类是抽象的,概念的,代表一类事物,比如人类,猫类.., 即它是数据类型.

  2. 对象是具体的,实际的,代表一个具体事物, 即 是实例.

  3. 类是对象的模板,对象是类的一个个体,对应一个实例

public class Object01 {
public static void main(String[] args) {
//使用 OOP 面向对象解决
//实例化一只猫[创建一只猫对象]
//老韩解读
//1. new Cat() 创建一只猫(猫对象)
//2. Cat cat1 = new Cat(); 把创建的猫赋给 cat1
//3. cat1 就是一个对象
Cat cat1 = new Cat();
cat1.name = "小白";
cat1.age = 3;
cat1.color = "白色";
cat1.weight = 10;
//创建了第二只猫,并赋给 cat2
//cat2 也是一个对象(猫对象)
Cat cat2 = new Cat();
cat2.name = "小花";
cat2.age = 100;
cat2.color = "花色";
cat2.weight = 20;
//怎么访问对象的属性呢
System.out.println("第 1 只猫信息" + cat1.name
+ " " + cat1.age + " " + cat1.color + " " + cat1.weight);
System.out.println("第 2 只猫信息" + cat2.name
+ " " + cat2.age + " " + cat2.color + " " + cat2.weight);
}
}
//使用面向对象的方式来解决养猫问题
//定义一个猫类 Cat -> 自定义的数据类型
class Cat {
//属性/成员变量
String name; //名字
int age; //年龄
String color; //颜色
//double weight; //体重
//行为
}

7.1.1 对象在内存中的存在形式 (重要)

7.1.2 属性 / 成员变量

  • 基本介绍:从概念或叫法上看: 成员变量 = 属性 = field(字段) (即 成员变量是用来表示属性的,授课中,统一叫 属性) 案例演示:Car(name,price,color)
  • 细节
    • 属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;
    • 这里老师简单的介绍访问修饰符: 控制属性的访问范围 有四种访问修饰符 public, proctected, 默认, private ,后面我会详细介绍
    • 属性的定义类型可以为任意类型,包含基本类型或引用类型
    • 属性如果不赋值,有默认值,规则和数组一致。具体说: int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000, boolean false,String null
public class PropertiesDetail {
public static void main(String[] args) {
//创建Person对象
//p1 是对象名(对象引用)
//new Person() 创建的对象空间(数据)才是真正的对象
Person p1 = new Person(); //对象的属性默认值,遵守数组规则
// 属性如果不赋值,有默认值,规则和数组一致。具体说: int 0,short 0, byte 0, long 0,
// float 0.0,double 0.0,char \u0000,
// boolean false,String null
System.out.println("输出这个人的信息");
System.out.println("age=" + p1.age + " name=" + p1.name
+ " sal=" + p1.sal + " isPass=" + p1.isPass);
}
}
class Person{
//四个属性
int age;
String name;
double sal;
boolean isPass;
}

7.1.3 类与对象的内存分配机制(重要)

  1. 栈: 一般存放基本数据类型(局部变量)
  2. 堆: 存放对象(Cat cat , 数组等)
  3. 方法区:常量池(常量,比如字符串), 类加载信息
  4. 示意图 [Cat (name, age, price)
  5. 赋值:赋的是地址值

Object03

public class Object03 {
public static void main(String[] args) {
Person1 p1 = new Person1();
p1.age = 10;
p1.name = "小明";
Person1 p2 = p1; //把p1 赋给了 p2 ,也就是把 p1 地址值赋给了 p2
System.out.println(p2.age);//10
}
}
class Person1{
//四个属性
int age;
String name;
}

Java创建对象的流程简单分析
Person p = new Person();
p.name = “jack”;
p.age = 10;
1) 先加载 Person 类信息(属性和方法信息, 只会加载一次)
2) 在堆中分配空间, 进行默认初始化(看规则)
3) 把地址赋给 p , p 就指向对象
4) 进行指定初始化, 比如 p.name =”jack” p.age = 10;

Object04

Person a=new Person();
a.age=10;
a.name="小明";
Person b;
b=a;
System.out.println(b.name);//小明
b.age=200;
b =null; //把 b 的地址值变成 null
System.out.println(a.age);//200
System.out.println(b.age);//异常

7.2 成员方法

7.2.1 成员方法的定义

访问修饰符 返回数据类型 方法名(形参列表..) {//方法体
语句;
return 返回值; }
  1. 形参列表:表示成员方法输入 cal(int n) , getSum(int num1,
  2. 返回数据类型:表示成员方法输出, void 表示没有返回值
  3. 方法主体:表示为了实现某一功能代码块
  4. return 语句不是必须的。
  5. 老韩提示: 结合前面的题示意图, 来理解
public class Method01 {
public static void main(String[] args) {
Person03 p1 = new Person03();
p1.cal02(5);
//调用getSum方法,同时num1 = 10;num2 = 20;
//把 方法 getSum 返回的值,赋给 变量 returnRes
int returnRes = p1.getSum(10,20);
System.out.println("getSum方法返回的值=" + returnRes);
}
}
class Person03{
String name;
int age;
//方法(成员方法)
//添加speak 成员方法,输出“我是一个好人”
//
public void cal01(){
System.out.println("我是一个好人");
} //添加cal02 成员方法 该方法可以接收一个数 n , 计算 1 + …… + n 的结果
//老韩解读
//1.(int n )形参列表, 表示当前有一个 形式参数 n ,可以直接用户输入
public void cal02(int n ){
int sum = 0;
for (int i = 1; i <= n; i++){
sum += i;
}
System.out.println("cal02 的值为=" + sum);
}
//添加getSum成员方法,可以计算两个数的和
//public 表示方法是公开的
//int :表示方法执行后,返回一个int 值
//getSum:方法名
//(int num1, int num2)形式参数,2个形参,可以接收用户传入的两个数
//return res:表示把 res 的值,返回
public int getSum(int num1, int num2){
int res = num1 + num2;
return res;
}
}
  • 遍历数组
public class Method02 {
public static void main(String[] args) {
//请遍历一个数组
int[][] map = {{0,0,1},{1,1,1},{1,1,3}}; //使用方法完成输出,创建Mytools对象,tool
MyTools tool = new MyTools();
tool.printArr(map); //遍历map数组
// 传统解决方式:解决思路1
// for (int i = 0; i <= map.length; i++){
// for (int j = 0; j < map[i].length; j++){
// System.out.print(map[i][j] + " ");
// }
// System.out.println("");
// }
}
}
//把输出功能,写在一个类的方法中,然后调用该方法
class MyTools{
public void printArr(int[][] map){
for (int i = 0; i <= map.length; i++){
for (int j = 0; j <= map[i].length; j++){
System.out.print(map[i][j] + " ");
}
System.out.println("");
}
}
}

7.2.2 方法的调用机制

7.2.3 方法使用的细节 1

  • 访问修饰符 (作用是控制 方法使用的范围) 如果不写默认访问
  1. [有四种: public, protected, 默认, private], 具体在后面说
  • 返回数据类型
  1. 一个方法最多有一个返回值 [思考,如何返回多个结果 返回数组 ]
  2. 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
  3. 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和 return 的 值类型一致或兼容
  4. 如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return ;
  5. 方法名 遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规范
  • 形参列表
  1. 方法可以有0个参数,也可以有多个参数,中间用逗号隔开, 比如:getSum(int n1,int n2)
  2. 参数类型可以为任意类型,包含基本类型或引用类型, 比如:printArr(int[]map)
  3. 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数!【getSum)
  4. 方法定义时的参数称为形式参数,简称形参;方法调用时的传入参数称为实际参数,简称实参
  5. 实参和形参的类型要一致或兼容、个数、顺序必须一致!
  • 方法体
  1. 里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义。
public class MethodDetail {
public static void main(String[] args) {
AA a = new AA();
int[] res = a.getSumAndSub(2,3); //2,3实参
System.out.println("差=" + res[0]);
System.out.println("和=" + res[1]);
}
}
class AA { //1. 一个方法最多有一个返回值 [思考,如何返回多个结果 返回数组]
public int[] getSumAndSub(int n ,int m){ // n , m 形参
int[] resArr = new int[2];
resArr[0] = n - m;
resArr[1] = n + m;
return resArr;//可以通过返回数组来实现 // 2.返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
// 具体看 getSumAndSub //3. 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值;
// 而且要求返回值类型必须和 return
public double f1(){
double d1 = 1.1 * 3;
int n = 100;
// return n;
return d1; //类型兼容 //4.如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return ; public void f2(){
System.out.println("hello world");
// return ;//可以写,但不要代值
} // 5.老韩提示:在实际工作中,我们的方法都是为了完成某个功能,所以方法名要有一定含义
// 最好是见名知意
}
}
}

7.2.4 方法调用的细节 2

  1. 同一个类中的方法调用:直接调用即可。 比如print(参数); 案例演示:A类sayOk 调用print()
  2. 跨类中的方法A类调用B类方法:需要通过对象名调用。 比如对象名.方法名(参数); 案例演示:B类sayHello调用print()
public class MethodDetail02 {
public static void main(String[] args) {
A a = new A();
a.sayOk();
a.m1();
}
}
class A {
//同一个类中的方法调用:直接调用即可
public void print(int n ){
System.out.println("print()方法被调用 n=" + n);
}
public void sayOk(){ //sayOk调用print
print(10);
System.out.println("继续执行sayOk");
} //跨类中的方法A类调用B类方法:需要通过对象名调用
public void m1(){
System.out.println("m1方法被调用");
//创建一个B类的对象
B b = new B();
b.hi();
System.out.println("m1() 继续执行");
}
} class B{
public void hi(){
System.out.println("B类中的 hi()被执行");
}
}

7.2.5 练习题 (成员方法)

import java.util.Scanner;

public class MethodExercise01 {
public static void main(String[] args) { Scanner sc = new Scanner(System.in);
System.out.println("请输入你判断的数字");
int num = sc.nextInt();
AA01 a = new AA01();
if (a.b(num)){
System.out.println("是一个偶数");
}else {
System.out.println("是一个奇数");
} //使用print方法
a.print(4,4,'#'); }
}
class AA01 {
// 编写类 AA ,有一个方法:判断一个数是奇数 odd 还是偶数, 返回 boolean
//思路:
//1.方法的返回类型 boolean
//2.方法的名字 b
//3.方法的形参(int n)
//4.方法体,判断
public boolean b(int n){ // if (n % 2 == 0){
// return true;
// }else {
// return false;
// }
// return n % 2 == 0 ? true:false;
return n % 2 == 0;
} // 2) 根据行、列、字符打印 对应行数和列数的字符,比如:行:4,列:4,字符#,则打印相应的效果
//思路:
//1.方法的返回类型 void
//2.方法的名字 print
//3.方法的形参(int row ,int col,char c)
//4.方法体,循环
public void print(int row ,int col,char c){
for (int i = 1; i <= row; i++){
for (int j = 1; j <= col; j++){
System.out.print(c + " ");
}
System.out.println("");
}
}
}

7.2.6 成员方法的传参机制 (非常重要)

1. 基本数据类型的传参机制

  • 结论:基本数据类型,传递的是值(值拷贝),形参的任何改变不会影响实参

public class MethodParameter01 {
public static void main(String[] args) {
int a = 10;
int b = 20;
//创建对象AA,名字obj
AA02 obj = new AA02();
obj.swap(a,b);
System.out.println("main方法中的a=" + a + "b=" + b);//a=10 b=20,因为主栈中的a,b 没有发生改变,所以这里不变
}
} class AA02 {
public void swap(int a, int b){
//交换之前
System.out.println("\na和b交换前的值\na=" + a + "\tb=" + b);//a=10 b=20 //完成 a 和 b 的交换
int temp = a;
a = b;
b = temp;
// swap这个栈发生的变化不会影响到其他栈,所以,main方法中的a,b没有发生改变
System.out.println("\na和b交换后的值\na=" + a + "\tb=" + b);//a=20 b=10,
}
}

2. 引用数据类型的传参机制

  • 结论:引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参

public class MethodParameter02 {
public static void main(String[] args) {
BB b = new BB();
int[] arr = {1, 2, 3};
b.Test100(arr);
System.out.println("main方法中的arr");
for (int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
} }
}
class BB{
public void Test100(int[] arr){
arr[0] = 200;
System.out.println("Test100方法中的arr");
for (int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}

3. 克隆对象

public class MethodExercise02 {
public static void main(String[] args) {
Person02 p = new Person02();
p.name = "joker";
p.age = 20; MyTools01 tools = new MyTools01();
Person02 p2 = tools.copyPerson(p); //到此 p 和 p2 是 Person 对象,但是是两个独立的对象,属性相同
System.out.println("p的属性 age =" + p.age + " 名字=" + p.name);
System.out.println("p2的属性 age =" + p2.age + " 名字=" + p2.name); //这里老师提示: 可以同 对象比较看看是否为同一个对象
System.out.println(p == p2);//false
}
}
class Person02{
String name;
int age;
}
class MyTools01{
// 编写一个方法 copyPerson,可以复制一个 Person 对象,返回复制的对象。克隆对象, 注意要求得到新对象和原来的
// 对象是两个独立的对象,只是他们的属性相同
//编写方法的思路
//1. 方法的返回类型 Person
//2. 方法的名字 copyPerson
//3. 方法的形参 (Person p)
//4. 方法体, 创建一个新对象,并复制属性,返回即可
public Person02 copyPerson(Person02 p){
//创建一个对象
Person02 p2 = new Person02();
p2.name = p.name;//把原来对象的名字赋给p2.name
p2.age = p.age;//把原来对象的名字赋给p2.age
return p2;
}
}

4. 方法递归调用

  • 简单的说: 递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂问题,同时可以让代码变 得简洁
4.1 打印问题
    public class Recursion01 { //打印问题
public static void main(String[] args) {
T t1 = new T();
t1.test(4); }
}
class T{
public void test(int n ){
if (n > 2){
test(n - 1);
}
System.out.println("n=" + n);
}
}
4.2 阶乘问题
public class Recursion01 { //打印问题
public static void main(String[] args) {
int res = t1.factorial(5);
System.out.println("res=" + res); }
}
class T{
public int factorial(int n){
if (n == 1){
return 1;
}else {
return factorial(n - 1)*n;
}
}
}
4.3 递归的重要规则
  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
  2. 方法的局部变量是独立的,不会相互影响,比如n变量
  3. 如果方法中使用的是引用类型变量(比如数组,对象),就会共享该引用类型的数据.
  4. 递归必须向退出递归的条件逼近,否则就是无限递归,出现(StackOverflowError,死龟了)
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。
4.4 汉诺塔
public class HanoiTower {
//编写一个 main 方法
public static void main(String[] args) {
Tower tower = new Tower();
tower.move(5, 'A', 'B', 'C');
}
}
class Tower {
//方法
//num 表示要移动的个数, a, b, c 分别表示 A 塔,B 塔, C 塔
public void move(int num , char a, char b ,char c) {
//如果只有一个盘 num = 1
if(num == 1) {
System.out.println(a + "->" + c);
} else {
//如果有多个盘,可以看成两个 , 最下面的和上面的所有盘(num-1)
//(1)先移动上面所有的盘到 b, 借助 c
move(num - 1 , a, c, b);
//(2)把最下面的这个盘,移动到 c
System.out.println(a + "->" + c);
//(3)再把 b 塔的所有盘,移动到 c ,借助 a
move(num - 1, b, a, c);
}
}
}
4.5 迷宫
public class MiGong {
//编写一个 main 方法
public static void main(String[] args) {
//思路
//1. 先创建迷宫,用二维数组表示 int[][] map = new int[8][7];
//2. 先规定 map 数组的元素值: 0 表示可以走 1 表示障碍物
int[][] map = new int[8][7];
//3. 将最上面的一行和最下面的一行,全部设置为 1
for(int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
//4.将最右面的一列和最左面的一列,全部设置为 1
for(int i = 0; i < 8; i++){
map[i][0] = 1;
map[i][6] = 1;
}
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1; //测试回溯
// map[2][1] = 1;
// map[2][2] = 1;
// map[1][2] = 1;
//输出当前的地图
System.out.println("=====当前地图情况======");
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");//输出一行
}
System.out.println();
}
//使用 findWay 给老鼠找路
T0 t1 = new T0();
//下右上左
t1.findWay(map, 1, 1);
System.out.println("\n====找路的情况如下=====");
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");//输出一行
}
System.out.println();
}
}
}
class T0 {
//使用递归回溯的思想来解决老鼠出迷宫
//老韩解读
//1. findWay 方法就是专门来找出迷宫的路径
//2. 如果找到,就返回 true ,否则返回 false
//3. map 就是二维数组,即表示迷宫
//4. i,j 就是老鼠的位置,初始化的位置为(1,1)
//5. 因为我们是递归的找路,所以我先规定 map 数组的各个值的含义
// 0 表示可以走 1 表示障碍物 2 表示可以走 3 表示走过,但是走不通是死路
//6. 当 map[6][5] =2 就说明找到通路,就可以结束,否则就继续找.
// 7. 先确定老鼠找路策略 下->右->上->左
public boolean findWay(int[][] map , int i, int j) {
if(map[6][5] == 2) {//说明已经找到
return true;
} else {
if(map[i][j] == 0) {//当前这个位置 0,说明表示可以走
//我们假定可以走通
map[i][j] = 2;
//使用找路策略,来确定该位置是否真的可以走通
//下->右->上->左
if(findWay(map, i + 1, j)) {//先走下
return true;
} else if(findWay(map, i, j + 1)){//右
return true;
} else if(findWay(map, i-1, j)) {//上
return true;
} else if(findWay(map, i, j-1)){//左
return true;
} else {
map[i][j] = 3;
return false;
}
} else { //map[i][j] = 1 , 2, 3
return false;
}
}
}
//修改找路策略,看看路径是否有变化
//下->右->上->左 ==> 上->右->下->左
public boolean findWay2(int[][] map , int i, int j) {
if(map[6][5] == 2) {//说明已经找到
return true;
} else {
if(map[i][j] == 0) {//当前这个位置 0,说明表示可以走
//我们假定可以走通
map[i][j] = 2;
//使用找路策略,来确定该位置是否真的可以走通
//上->右->下->左
if(findWay2(map, i - 1, j)) {//先走上
return true;
} else if(findWay2(map, i, j + 1)){//右
return true;
} else if(findWay2(map, i+1, j)) {//下
return true;
} else if(findWay2(map, i, j-1)){//左
return true;
} else {
map[i][j] = 3;
return false;
}
} else { //map[i][j] = 1 , 2, 3
return false;
}
}
}
}

7.3 方法的重载

  1. java 中允许同一个类中,多个同名方法的存在,但要求形参列表不一致
  2. 方法名:必须相同
  3. 形参列表:必须不同(形参类型或个数或顺序,至少有一样不同参数名无要求)
  4. 返回类型:无要求

练习

public class OverLoadExercise {
//编写一个 main 方法
public static void main(String[] args) {
//在主类的 main ()方法中分别用参数区别调用三个方法
Methods method = new Methods();
method.m(10);//100
method.m(10, 20);//200
method.m("韩顺平教育 hello");//字符串信息
//测试
System.out.println(method.max(10, 24)); // 24
System.out.println(method.max(10.0, 21.4)); // 21.4
System.out.println(method.max(10.0, 1.4, 30.0)); // 30.0
}
}
/*
编写程序,类 Methods 中定义三个重载方法并调用。方法名为 m。
三个方法分别接收一个 int 参数、两个 int 参数、一个字符串参数。分别执行平方运算并输出结果,
相乘并输出结果,输出字符串信息。在主类的 main ()方法中分别用参数区别调用三个方法
定义三个重载方法 max(),第一个方法,返回两个 int 值中的最大值,
第二个方法,返回两个 double 值中的最大值,第三个方法,
返回三个 double 值中的最大值,并分别调用三个方法
*/
class Methods {
//分析
//1 方法名 max
//2 形参 (int,int)
//3.int
public int max(int n1, int n2) {
return n1 > n2 ? n1 : n2;
}
//分析
//1 方法名 max
//2 形参 (double,double)
//3.double
public double max(double n1, double n2) {
return n1 > n2 ? n1 : n2;
}
//分析
//1 方法名 max
//2 形参 (double,double,double)
//3.double
public double max(double n1, double n2, double n3) {
System.out.println("max(double n1, double n2, double n3)");
//求出 n1 和 n2 的最大值
double max1 = n1 > n2 ? n1 : n2;
return max1 > n3 ? max1 : n3;
}
public double max(double n1, double n2, int n3) {
System.out.println("max(double n1, double n2, int n3)");
//求出 n1 和 n2 的最大值
double max1 = n1 > n2 ? n1 : n2;
return max1 > n3 ? max1 : n3;
}
//分析
//1 方法名 m
//2 形参 (int)
//3.void
public void m(int n) {
System.out.println("平方=" + (n * n));
}
//1 方法名 m
//2 形参 (int, int)
//3.void
public void m(int n1, int n2) {
System.out.println("相乘=" + (n1 * n2));
}
//1 方法名 m
//2 形参 (String)
//3.void
public void m(String str) {
System.out.println("传入的 str=" + str);
}
}

7.4 可变参数

1.基本

概念:java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。 就可以通过可变参数实现

语法:访问修饰符 返回类型 方法名(数据类型... 形参名) { }

  1. 可变参数的实参可以为0个或任意多个。
  2. 可变参数的实参可以为数组。
  3. 可变参数的本质就是数组.
  4. 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
  5. 一个形参列表中只能出现一个可变参数
public class VarParameterDetail {
//编写一个 main 方法
public static void main(String[] args) {
//细节: 可变参数的实参可以为数组
int[] arr = {1, 2, 3};
TA t1 = new TA();
t1.f1(arr);
}
}
class TA {
public void f1(int... nums) {
System.out.println("长度=" + nums.length);
}
//细节: 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
public void f2(String str, double... nums) {
}
//细节: 一个形参列表中只能出现一个可变参数
//下面的写法是错的.
// public void f3(int... nums1, double... nums2) {
// }
}

练习:

public class VarParameterExercise {
//编写一个 main 方法
public static void main(String[] args) {
HspMethod hm = new HspMethod();
System.out.println(hm.showScore("milan" , 90.1, 80.0 ));
System.out.println(hm.showScore("terry" , 90.1, 80.0,10,30.5,70 ));
}
}
class HspMethod {
/*
有三个方法,分别实现返回姓名和两门课成绩(总分),
返回姓名和三门课成绩(总分),返回姓名和五门课成绩(总分)。
封装成一个可变参数的方法
*/
//分析 1. 方法名 showScore 2. 形参(String ,double... ) 3. 返回 String
//听课小伙伴,老师要求必须自己动手写
public String showScore(String name,double...score){
double totalScore = 0;
for(int i = 0; i < scores.length; i++) {
totalScore += scores[i];
}
return name + " 有 " +scores.length + "门课的成绩总分为=" + totalScore;
}
}

7.5 作用域(Scope)(重要)

1. 基本使用

  1. 在java编程中,主要的变量就是属性(成员变量)和局部变量。
  2. 我们说的局部变量一般是指在成员方法中定义的变量。【举例Cat类: cry)java中作用域的分类
  3. 全局变量:也就是属性,作用域为整个类体Cat类:cry eat等方法使用属性【举例】
  4. 局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!
  5. 全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值。[举例】
public class VarScope {
//编写一个 main 方法
public static void main(String[] args) {
}
}
class Cat {
//全局变量:也就是属性,作用域为整个类体 Cat 类:cry eat 等方法使用属性
//属性在定义时,可以直接赋值
int age = 10; //指定的值是 10
//全局变量(属性)可以不赋值,直接使用,因为有默认值,
double weight; //默认值是 0.0
public void hi() {
//局部变量必须赋值后,才能使用,因为没有默认值
int num = 1;
String address = "北京的猫";
System.out.println("num=" + num);
System.out.println("address=" + address);
System.out.println("weight=" + weight);//属性
}
public void cry() {
//1. 局部变量一般是指在成员方法中定义的变量
//2. n 和 name 就是局部变量
//3. n 和 name 的作用域在 cry 方法中
int n = 10;
String name = "jack";
System.out.println("在 cry 中使用属性 age=" + age);
}
public void eat() {
System.out.println("在 eat 中使用属性 age=" + age);
//System.out.println("在 eat 中使用 cry 的变量 name=" + name);//错误
}
}

2. 细节

  1. 属性和局部变量可以重名,访问时遵循就近原则。
  2. 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。[举例]
  3. 属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。
  4. 局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁.即在一次方法调用过程中。
  5. 作用域范围不同

    全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
  6. 局部变量:只能在本类中对应的方法中使用

    修饰符不同

    全局变量/属性可以加修饰符局部变量不可以加修饰符
public class VarScopeDetail{
//编写一个 main 方法
public static void main(String[] args) {
Person p1 = new Person();
/*
属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。
局部变量,生命周期较短,伴随着它的代码块的执行而创建,
伴随着代码块的结束而销毁。即在一次方法调用过程中
*/
//p1.say();//当执行 say 方法时,say 方法的局部变量比如 name,会创建,当 say 执行完毕后
//name 局部变量就销毁,但是属性(全局变量)仍然可以使用
//
TAC t1 = new TAC();
t1.test(); //第 1 种跨类访问对象属性的方式
t1.test2(p1);//第 2 种跨类访问对象属性的方式
}
}
class TAC {
//全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
public void test() {
Person p1 = new Person();
System.out.println(p1.name);//jack
}
public void test2(Person p) {
System.out.println(p.name);//jack
}
}
class Person {
//细节: 属性可以加修饰符(public protected private..)
// 局部变量不能加修饰符
public int age = 20;
String name = "jack";
public void say() {
//细节 属性和局部变量可以重名,访问时遵循就近原则
String name = "king";
System.out.println("say() name=" + name);
}
public void hi() {
String address = "北京";
//String address = "上海";//错误,重复定义变量
String name = "hsp";//可以
}
}

7.6 构造器

7.6.1 基本语法

[修饰符] 方法名(形参列表){
方法体;
}
1)构造器的修饰符可以默认, 也可以是 public protected private
2) 构造器没有返回值
3) 方法名 和类名字必须一样
4) 参数列表 和 成员方法一样的规则
5) 构造器的调用, 由系统完成

7.6.3 基本介绍

构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:

  1. 方法名和类名相同
  2. 没有返回值
  3. 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化。

7.6.4 快速入门

public class Constructor01 {
//编写一个 main 方法
public static void main(String[] args) {
//当我们 new 一个对象时,直接通过构造器指定名字和年龄
Person002 p1 = new Person002("smith", 80);
System.out.println("p1 的信息如下");
System.out.println("p1 对象 name=" + p1.name);//smith
System.out.println("p1 对象 age=" + p1.age);//80
}
}
//在创建人类的对象时,就直接指定这个对象的年龄和姓名
//
class Person002 {
String name;
int age; //构造器
//老韩解读
//1. 构造器没有返回值, 也不能写 void
//2. 构造器的名称和类 Person 一样
//3. (String pName, int pAge) 是构造器形参列表,规则和成员方法一样
public Person002(String pName, int pAge) {
System.out.println("构造器被调用~~ 完成对象的属性初始化");
name = pName;
age = pAge;
}
}

7.6.5 构造器的细节

  1. 一个类可以定义多个不同的构造器,即构造器重载
  2. 比如:我们可以再给Person类定义一个构造器,用来创建对象的时候,只指定人名,不需要指定年龄
  3. 构造器名和类名要相同
  4. 构造器没有返回值
  5. 构造器是完成对象的初始化,并不是创建对象在创建对象时,系统自动的调用该类的构造方法
  6. 如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器),比如Dog (){ },使用javap指令反编译看看
  7. 一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下,即:Dog(){ } 写(这点很重要
public class ConstructorDetail {
public static void main(String[] args) {
Person006 person006 = new Person006("King", 40);
Person006 person0061 = new Person006("tom"); Dog dog1 = new Dog();//使用的是默认的无参构造器 }
}
class Person006{
String name;
int age;//默认值 = 0
//第一个构造器
public Person006(String pName, int pAge){
name = pName;
age = pAge;
}
//第二个构造器,只指定人名
public Person006(String pName){
name = pName;
}
}
class Dog {
//如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器)
//使用 javap 指令 反编译看看
/*
默认构造器
Dog() {
}
*/
//一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,
//除非显式的定义一下,即: Dog(){} 写 (这点很重要)
//
public Dog(String dName) {
//... }
Dog() { //显式的定义一下 无参构造器
}
}

7.7 This关键字

7.7.1 This关键字细节

  1. this 关键字可以用来访问本类的属性、方法、构造器

  2. this 用于区分当前类的属性和局部变量

  3. 访问成员方法的语法:this.方法名(参数列表);

  4. 访问构造器语法:this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器, 必须放在第一 条语句)

  5. this 不能在类定义的外部使用,只能在类定义的方法中使用。

public class ThisDetail {
public static void main(String[] args) {
T2 t2 = new T2();
}
}
class T2{
String name = "jack";
int num = 100; // 细节4:访问构造器语法:this(参数列表); 注意只能在构造器中使用
// (即只能在构造器中访问另外一个构造器, 必须放在第一 条语句)
public T2(){
//这里去访问 T2(String name, int age).
//注意:即只能在构造器中访问另外一个构造器, 必须放在第一 条语句
this("jack",20);
System.out.println("T() 构造器");
}
public T2(String name, int age){
System.out.println("T2(String name, int age) 构造器");
}
// 细节3:访问成员方法的语法:this.方法名(参数列表);
public void f1(){
System.out.println("f1() 方法。");
}
public void f2(){
System.out.println("f2() 方法。");
//调用本类的f1
//第一种方式
f1();
//第二种方式
this.f1();
}
// 细节1:this 关键字可以用来访问本类的属性、方法、构造器
public void f3(){
System.out.println("name=" + this.name + "num=" + this.num);
}
}

7.7.2 练习

public class TestPerson {
//编写一个 main 方法
public static void main(String[] args) {
Person p1 = new Person("mary", 20);
Person p2 = new Person("mary", 20);
System.out.println("p1 和 p2 比较的结果=" + p1.compareTo(p2));
}
}
/*
定义 Person 类,里面有 name、age 属性,并提供 compareTo 比较方法,
用于判断是否和另一个人相等,提供测试类 TestPerson 用于测试, 名字和年龄完全一样,就返回 true, 否则返回 false
*/
class Person {
String name;
int age;
//构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//compareTo 比较方法
public boolean compareTo(Person p) {
//名字和年龄完全一样
// if(this.name.equals(p.name) && this.age == p.age) {
// return true;
// } else {
// return false;
// }
return this.name.equals(p.name) && this.age == p.age;
}
}

总结:

  • 简单说就是,哪个对象调用,this就代表哪个对象

本章作业

public class Homework01 {
public static void main(String[] args) {
A01 a01 = new A01();
double[] arr = {1.0,5.6,5.7};
Double res = a01.max(arr);
if (res != null) {
System.out.println(a01.max(arr));
} else {
System.out.println("arr的输入有误");
}
}
}
/*
编写类A01,定义方法max,实现求某个double数组的最大值,并返回 思路分析
1.类名 A01
2.方法名 max
3.形参 (double[])
4.返回值 double
*/
class A01{
public Double max(double[] num){
//先判断数组是否为空,再判断
if ( num != null && num.length > 0) {
double max = num[0];//假设第一个为最大值
for (int i = 0; i < num.length; i++) {
if (max < num[i]) {
max = num[i];
}
}
return max;
}else{
return null;
}
}
}
public class Homework02 {
public static void main(String[] args) {
String[] strs = {"jack", "tom","mary","milan"};
A02 a02 = new A02();
int index = a02.find("tom",strs);
if (index == -1) {
System.out.println("没有找到");
} else {
System.out.println(index);
} }
}
//2.编写类A02,定义方法find,实现查找某字符串是否在字符串数组中,并返回索引,如果找不到,返回-1. Homework02.java class A02{
public int find(String findStr, String[] strs) {
//直接遍历字符串数组,找到,返回索引值 for (int i = 0; i < strs.length; i++) {
if (findStr.equals(strs[i])) {
return i;
}
}
return -1;
}
}
public class Homework03 {
public static void main(String[] args) {
Book book = new Book("笑傲江湖",30);
book.info();
book.updatePrice();
book.info();
}
}
//3.编写类Book,定义方法updatePrice,实现更改某本书的价格,具体:
//如果价格>150,则更改为150,如果价格>100,更改为100,否则不变HomeworkO3.java-定要自己写代码
//分析
/*
1.类名 Book
2.属性 price name
3.方法名 updatePrice
4.形参()
5。返回值,void
*/
class Book{
String name;
int price;
public Book(String name, int price){
this.name = name;
this.price = price;
}
public void updatePrice(){
//如果方法中,没有 price 局部变量,this.price 等价 price
if (this.price > 150){
this.price = 150;
}else if (this.price > 100){
this.price = 100;
}
}
//显示书籍情况
public void info(){
System.out.println("书名=" + this.name + " " + "价格=" + this.price);
}
}
public class Homework04 {
public static void main(String[] args) {
int[] oldArr = {2,5,6,7};
A03 a03 = new A03();
int[] res = a03.copeArr(oldArr);
for (int i = 0; i < res.length; i++){
System.out.println(res[i]);
} }
}
//4.编写类AO3,实现数组的复制功能copyArr,输入旧数组,返回一个新数组,元素和旧数组一样Homework04.java
class A03{
public int[] copeArr(int[] oldArr){
System.out.println("调用此方法");
int[] newArr = new int[oldArr.length];
for (int i = 0; i < oldArr.length; i++){
newArr[i] = oldArr[i];
}
return newArr;
}
}
public class Homework05 {
public static void main(String[] args) {
Circle circle = new Circle(5);
System.out.println("周长为:" + circle.c());
System.out.println("面积为:" + circle.s());
}
}
//5.定义一个圆类Circle,定义属性:半径,提供显示圆周长功能的方法,提供显示圆面积的方法HomeworkO5.java
class Circle{
double r;
public Circle(double r){
this.r = r;
}
public double c(){
double num = 2 * Math.PI * r;
return num;
}
public double s(){
double num = r * r * Math.PI;
return num;
}
}
public class Homework06 {
public static void main(String[] args) {
Cale cale = new Cale(5, 0);
System.out.println("两数相加=" + cale.sum());
System.out.println("两数相减=" + cale.minus());
System.out.println("两数相乘=" + cale.multiply());
Integer divRes = cale.div();
if (divRes != null) {
System.out.println("两数相除=" + cale.div());
} }
}
//6.编程创建一个Cale计算类,在其中定义2个变量表示两个操作数,
//定义四个方法实现求和、差、乘、商(要求除数为0的话,要提示)并创建两个对象,分别测试
class Cale{
int a;
int b;
public Cale(int a,int b){
this.a = a;
this.b = b;
}
public int sum(){
return a + b;
}
public int minus(){
return a - b;
}
public int multiply(){
return a * b;
}
public Integer div() {
//判断
if (b == 0) {
System.out.println("除数不能为0");
return null;
} else {
return a / b;
}
}
}
public class Homework07 {
public static void main(String[] args) {
Dog01 dog01 = new Dog01("小花", 2, "花色");
dog01.show();
}
}
class Dog01{
String name;
int age;
String color;
public Dog01(String name, int age, String color){
this.name = name;
this.age = age;
this.color = color;
}
public void show(){
System.out.println("狗名是=" + name + "年龄是=" + age + "颜色是=" + color );
}
}
public class Homework09 {
public static void main(String[] args) {
Music music = new Music("哈哈哈", 36);
music.play();
System.out.println(music.getInfo()); }
}
//9.定义Music类,里面有音乐名name、音乐时长times属性,
// 并有播放play功能和返回本身属性信息的功能方法getInfo. Homework09.java
class Music{
String name;
double times; public Music(String name,double times){
this.name = name;
this.times = times;
}
public void play(){
System.out.println("音乐" + name + "正在播放中……时长" + times + "秒");
}
public String getInfo(){
return "音乐" + name + "播放时间为" + times;
}
}
class Demo {
int i = 100;
public void m() {
int j = i++;
System.out.println("i=" + i);//101
System.out.println("j=" + j);//100
}
}
class Homework10 {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = d1;//把d1 值赋给d2
d2.m();
//下面两句话指向的都是同一个对象
System.out.println(d1.i);//101
System.out.println(d2.i);//101
}
}
public class Homework12 {
public static void main(String[] args) { }
}
//12.创建一个Employee类,属性有(名字,性别,年龄,职位,薪水),提供3个构造方法,
//可以初始化(1)(名字,性别,年龄,职位,薪水),(2)(名字,性别,年龄)(3)(职位,薪水).要求充分复用构造器Homework12.java
class Employee{
String name;
char gender;
int age;
String posts;//职位
double salary; public Employee(String name, char gender,int age){
this.name = name;
this.gender = gender;
this.age = age;
}
public Employee(String posts,double salary){
this.posts = posts;
this.salary = salary;
}
public Employee(String name, char gender,int age,String posts,double salary){
this(name,gender,age);//这就是复用构造器,用this调用别的构造器,必须排在第一位,即后面不能在调用其他的构造器
this.posts = posts;
this.salary = salary;
}
}

猜拳

public class Homework13 {
public static void main(String[] args) {
Circle02 circle = new Circle02();
PassObject po = new PassObject();
po.printAreas(circle,5);
}
}
/*
13.将对象作为参数传递给方法。Homework13.java题目要求:
(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,findArea()方法返回圆的面积。
(2)定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下:
public void printAreas(Circle c, int times)//方法签名/声明
(3)在printAreas方法中打印输出1到times之间的每个整数半径值,以及对应的面积。例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积。
(4)在main方法中调用printAreas()方法,调用完毕后输出当前半径值。程序运行结果如图所示,
老韩提示,如果还是不明确,自己画一个内存图,一定可以搞定
*/
class Circle02{ //类
double radius; //半径
public Circle02(){ //无参构造器 }
public Circle02(double radius){
this.radius = radius;
}
public double findArea(){
return radius * radius * Math.PI;
}
//添加一个方法setRadius,修改对象的半径值
public void setRadius(double radius){
this.radius = radius;
}
}
class PassObject{
public void printAreas(Circle02 c,int times){
System.out.println("radius\tarea");
for ( int i = 1; i <= times; i++){
c.setRadius(i);
System.out.println((double) i + "\t" + c.findArea()); }
}
}
import java.util.Random;
import java.util.Scanner; public class Homework14 {
public static void main(String[] args) {
//创建一个玩家对象
Tom t = new Tom();
//用来记录最后输赢的次数
int isWinCount = 0; //创建二维数组,用来接收局数,Tom出拳情况及电脑出拳情况
int[][] arr1 = new int[3][3];
int j = 0; //创建一个一维数组,用来接受输赢情况
String[] arr2 = new String[3]; //获取玩家的出拳
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
System.out.println("数字0-表示石头,数字1-表示剪刀,数字2-表示布");
System.out.println("请输入你的数字");
int tomNum = sc.nextInt();
t.setTomGuessNum(tomNum);
int tomGuess = t.getTomGuessNum();
arr1[i][j + 1] = tomGuess; //获取电脑的出拳
int comGuess = t.computerNum();
arr1[i][j + 2] = comGuess; //将玩家猜的拳与电脑做对比
String isWin = t.vsComputer();
arr2[i] = isWin;
arr1[i][j] = t.count; //对每一局的情况进行输出
System.out.println("===========================");
System.out.println("局数\t玩家的出拳\t电脑的出拳\t输赢情况");
System.out.println(t.count + "\t" + tomGuess + "\t\t" + comGuess + "\t\t" + isWin);
System.out.println("===========================");
System.out.println("\n\n");
isWinCount = t.winCount(isWin);
} //对游戏的最终结果进行输出
System.out.println("局数\t玩家出拳\t电脑出拳\t\t输赢情况");
for (int a = 0; a < arr1.length; a++){
for (int b = 0; b < arr1[a].length; b++){
System.out.println(arr1[a][b] + "\t\t\t");
} System.out.println(arr2[a]);
System.out.println();
}
System.out.print("你赢了" + isWinCount + "次"); }
}
/*
思路
1.随机生成0,1,2
*/
class Tom{
//玩家出拳
int tomGuessNum;
//电脑出拳
int comGuessNum;
//赢的次数
int winCountNum;
//比赛的次数
int count = 1;//一共比赛三次 //电脑随机猜拳的数字的方法
public int computerNum(){
Random r = new Random();
comGuessNum = r.nextInt(3);// 方法 返回 0 - 2的随机数
return comGuessNum;
}
//规定玩家的玩法
public void setTomGuessNum(int tomGuessNum){
if (tomGuessNum > 2 || tomGuessNum < 0){
throw new IllegalArgumentException("数字输入有误");
}
this.tomGuessNum = tomGuessNum;
}
public int getTomGuessNum(){
return tomGuessNum;
}
//比较
public String vsComputer(){
if (tomGuessNum == 0 && comGuessNum == 1){
return "你赢了";
}else if (tomGuessNum == 1 && comGuessNum ==2) {
return "你赢了";
}else if (tomGuessNum == 2 && comGuessNum ==0) {
return "你赢了";
}else if (tomGuessNum == comGuessNum){
return "平手";
}else {
return "你输了";
}
}
public int winCount(String s){
count++;
if (s.equals("你赢了")){
winCountNum++;
}
return winCountNum;
}
}

Chaoter07 面向对象 (Object)的更多相关文章

  1. 理解JAVA - 面向对象(object) - 属性,方法

    理解JAVA - 面向对象(object) - 属性,方法 多态的体现:    向上造型,父类接收子类对象:向上造型:    从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...

  2. Java - 面向对象(object oriented)计划 详细解释

    面向对象(object oriented)计划 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24058107 程序包括 ...

  3. Java面向对象 Object类 内部类

     Java面向对象 Object类    内部类 知识概要:                 一:Object类                 二:内部类 匿名内部类的写法 1.Object O ...

  4. 面向对象object与constructor

    什么是constructor属性?它来自哪里?又将会指向何处? 什么是constructor属性? constructor是构造函数属性. 它来自哪里? 其实constructor属性是来自 prot ...

  5. 面向对象-Object类

    一.Object类中的equals()方法 equals(Object obj) :指示其它某个对象是否与此对象"相等". 返回值类型是boolean Oblect类中的equal ...

  6. ABAP 面向对象(Object Orientation) OO

    [转自 http://blog.sina.com.cn/s/blog_7c7b16000101bhof.html]在程序中, 对象的识别和寻址是通过对象引用来实现的, 对象引用变量可以访问对象的属性和 ...

  7. php面向对象Object

    1.创建类 class 类名{ private 私有变量 只能本类的内部使用 protected 受保护的变量 本类和子类的内部 public 公开的变量 都可以使用 一般属性都设为私有 一般函数都是 ...

  8. OC中的面向对象语法

    一. 面向对象和面向过程思想 OC是面向对象的,C是面向过程的.面向对象和面向过程只是解决问题的两种不同思想 1. 面向对象和面向过程的区别 1) 以用电脑听歌为例子 a) 面向过程 打开电脑 播放电 ...

  9. 【java基础】面向过程~面向对象

    相信大家都知道这两个东西,可是大家是如何知道的呢?我们又该如何区分这个东西到底是面向过程还是面向对象的呢? 那,我们首先就要知道什么是面向过程,什么是面向对象: 面向过程"(Procedur ...

随机推荐

  1. linux网卡知识

    使用 Vim 文本编辑器来配置网卡设备的绑定参数.网卡绑定的理论知识类似于前面学习的 RAID 硬盘组,我们需要对参与绑定的网卡设备逐个进行"初始设置".需要注意的是,这些原本独立 ...

  2. python小兵之时间模块

    Python  日期和时间 Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间. 时间 ...

  3. Loadrunner11录制移动端测试脚本(原文:http://blog.csdn.net/zhailihua/article/details/73610317)

    一.LR配置 1)LR设置代理,利用手机录制脚本 1-协议选择Web(HTTP/HTML)协议即可 2-录制开始前,对Recoding Options中的Port Mapping配置如下 a.新建Ne ...

  4. HDOJ 1249 三角形『平面分隔』

    很水拉   为了记规律- - 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1249 分隔平面公式 下面是我自己查找的公式,没有推到过程,但可以给一些链 ...

  5. CheckStyle使用手册(一)

    介绍 CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具.它能够自动化代码规范检查过程,从 而使得开发人员从这项重要,但是枯燥的任务中解脱出 ...

  6. web虚拟主机、日志分割以及日志分析

    目录 一.构建虚拟web主机 1.1 概述 1.2 支持的虚拟主机类型 1.3 部署虚拟主机步骤 1.3.1 基于域名的虚拟主机 (1)为虚拟主机提供域名解析 (2)为虚拟主机准备网页文档 (3)添加 ...

  7. JS快速入门(二)

    目录 JS快速入门(二) 结构图 BOM window对象 open() window子对象 location对象 history对象(了解) navigator 对象 screen对象 BOM 定时 ...

  8. 实现基于MYSQL验证的vsftpd虚拟用户访问

    一.配置mysql服务器 1.1 安装mysql # yum -y install mariadb-server # systemctl enable --now mariadb.service &a ...

  9. 从 MMU 看内存管理

    在计算机早期的时候,计算机是无法将大于内存大小的应用装入内存的,因为计算机读写应用数据是直接通过总线来对内存进行直接操作的,对于写操作来说,计算机会直接将地址写入内存:对于读操作来说,计算机会直接读取 ...

  10. SpringBoot外部配置属性注入

    一.命令行参数配置 Spring Boot可以是基于jar包运行的,打成jar包的程序可以直接通过下面命令运行: java -jar xx.jar 那么就可以通过命令行改变相关配置参数.例如默认tom ...