面向对象 上(四)

Java面向对象 ( 上 )

观看b站尚硅谷视频做的笔记

1、 面向过程 (POP) 与面向对象 (OOP)

2、类和对象

2.1、Java 类及类的成员

属性:对应类中的成员变量
行为:对应类中的成员方法。

2.2、类与对象的创建及使用

一、设计类,就是设计类的成员。

现在主要讲两个类的成员:属性、方法
属性==成员变量=field=域、字段
方法=成员方法=函数=method
创建类的对象=类的实例化=实例化类

设计类:
class Person{
//属性
//方法

}
在这里插入图片描述

设计好类后需要用它:即就要造对象
在这里插入图片描述
测试类作为程序的入口:
类是引用型变量
Person P1 = new Person();创建类的对象,类的实列化

创建完对象,就可以调用对象的功能
调用对象的结构体现为属性、方法
// 调用属性:对象 . 属性

	P1.name = "Tom";给变量赋值

在这里插入图片描述
Person p3 = p1;把p1对象的地址赋给p3,把p1变量保存的对象地址值赋给p3,导致p1和p3指向了同一个堆空间中的同一个对象实体。
System.out.println(p3.name);Tom
p3.age = 10;
System.out.println(p1.age); //10 修改了p3也就是修改p1

2.3、对象的创建和使用:内存解析

需要使用栈、堆的内存结构

运行时数据,加载时都在这里面

平时说的栈指的是虚拟机栈,虚拟机栈主要存放的是局部变量
堆(Heap):此内存区域的唯一目的就是存放对象实例(数组对象等)

方法区(MethodArea):用于存储已被虚拟机加载的类信息、常量(字符串String)、静态变量(static)、即时编译器编译后的代码等数据。

栈的特点:先进后出

Person P1 = new Person();造了一个对象,在堆中,对象在堆中会有一个地址,叫首地址值
右边赋给左边,赋的是地址
在栈空间中声明一个变量为p1,p1此时是定义在main方法中,main方法是方法,方法中的变量是局部变量,栈中存放的就是p1变量,通过地址值,栈空间中的p1指向了堆空间中p1

堆空间中
在类设计时,有三个属性,不同与局部变量,属性是存放在堆空间中,造好的对象中有name,age,isMale,还会考虑值的问题,name为null,age=1,isMale为false,第一行代码完事

P1.name = “Tom”;通过栈空间中的p1调name,找到name结构,改成TOM
TOM实际不在这里,在方法区的常量池中
P1.isMale = true;

Person p3 = p1;//栈空间又声明了一个P3,将p1的地址值赋给p3,通过地址值,p3指向了堆空间中的p1对象,p3不能叫新创建对象,顶多只能叫新声明的变量,此时p1和p3指向了堆空间中同一个实体
p3.age = 10;p3修改age,即p1再去调age即为10System.out.println(p1.age); //10

在这里插入图片描述

3、类的成员之一:属性类中属性的使用

属性(成员变量)vs局部变量

UserTest类

定义在类中大括号内的叫属性,成员变量
class user{
// 属性(或成员变量)
String name; // 不加 private 即为缺省
public int age;
boolean isMale
}

局部变量
局部变量也是变量,
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

//language:形参,也是局部变量
public void talk(String language){
System.out.println(" 我们使用 " + language + " 进行交流 ");

只要是变量,都是要先声明再使用

局部变量不可以使用权限修饰符
在这里插入图片描述
默认初始化值的情况:

User u1 = new User;
User u1 = new User;
System.out.println(u1.name);
System.out.println(u1.age);
System.out.println(u1.isMale);

局部变量没有初始化值
意味着:我们在调用局部变量之前,一定要显示赋值;
引用地:形参在调用时,赋值即可。

在这里插入图片描述
//language:形参,也是局部变量
public void talk(String language){
System.out.println(" 我们使用 " + language + " 进行交流 “);
}此处为啥language没有显示赋值,因为没有被调用
u1.talk(” 日语 ");调用时将日语赋值给language
形参是调用时赋值

方法内写的局部变量必须要显示声明

④ 在内存加载中的位置:
属性:加载到堆空间中(非 static);static的属性放在方法区
局部变量:加载到栈空间中。

4、类的成员之二:方法

public class CustomerTest{}

在类中,属性就相当于是定义的变量,直接描述对象的特点

方法是来刻画类中的功能

比如:Math 类:sqrt() / random() / …
Scanner 类:nextXxx() …
Arrays 类:sort() / binarysearch() …
tostring() / equals() / .

tostring() 是用来输出一个数组
在这里插入图片描述
在这里插入图片描述

  1. 举例:
    public void eat(){}void是没有返回值的意思
    public void sleep(int hour){}
    public String getName(){}
    public String getNation(String netion){}调方法是返回是字符串
    方法可以有形参也可以没有形参
    在这里插入图片描述
    方法的声明:权限修饰符、返回值类型、
    方法名(形参列表){
    方法体
    }

形参列表可有可无

注意:static、final、abstract 来修饰的方法,后面再讲
返回值类型:有返回值 VS 没有返回值细节,自己定义方法时是否有返回值
方法的使用中,可以调用当前类的属性和方法。
public String getName(){
if(age > 18){
return name;
}else{
return “Tom”;
}
}public void sleep(int hour){
System.out.println(" 休息了 " + hour + " 个小时 ");
eat();
// sleep(10);会栈溢出
}

4.1类中方法的声明和使用

4.2、理解“万事万物皆对象”

类怎么去理解,对象怎么理解
如何理解面向对象编程思想?
如何理解万事万物皆对象

在这里插入图片描述

4.3、内存解析的说明

在这里插入图片描述

数组本身是引用数据类型

Student[] stus=new Student[];数组元素在右边,数组元素可以是基本数据类型,也可以是引用类型,这个引用类型是自定义的类,类本身就是引用类型
即就是堆中数组中的每一项放的是Student类型,数组元素可以是任意类型
在这里插入图片描述
因为是引用类型,没有赋过值,即为null

下面就去赋值
stus[0]=new ;第一个去赋值,赋什么值看类型
是Student类型,就赋Student类型
Student是一个类,赋的值是一个对象,对象就得new,自然而然就得去new Student()
stus[0]=new Student();右边都在堆里

stus[0]=new Student()又在堆空间造了一个对象,又有一个首地址,即这个的地址值赋给数组的第一个元素,为Student类型的,
在这里插入图片描述
属性都是非静态的,即存在堆空间中,存在于实例中
在这里插入图片描述
属性都还没赋值
stus[1].number异常,报空指针异常,点之前是null,没有指针去指下面的结构,即就是空指针异常
在这里插入图片描述
保证让他不空指针,赋值即可
在这里插入图片描述
在这里插入图片描述

引用类型变量的值内存解析的说明
引用类型的变量,只能储存两类值:
null 或地址值(含变量的类型)。

在这里插入图片描述
在这里插入图片描述

4.4、匿名对象的使用

在这里插入图片描述
测试
在这里插入图片描述
p.sendEmail();
p.playGame();
这调的是同一个对象,都是指向堆空间中的new Phone()结构

  1. 理解:我们创建对象,没有显示的赋值给一个变
    量名,即为匿名对象。
  2. 匿名对象只能使用一次。
    new Phone()匿名对象,还要调属性,调方法
    new Phone().sendEmail();
    new Phone().playGame();这两个调的是同一个对象吗?不是
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
匿名对象后面还想再用,用不了。

开发中,匿名对象会不会用?
怎么用?

在这里插入图片描述
写了一个类,类里写了一个方法,里面有形参,形参是任意数据类型,自然也可以是Phone类型
在这里插入图片描述

想调show()方法,就得需要一个方法所在类的对象
在这里插入图片描述
调show方法就需要一个变量,是Phone类型,就传一个具体的值
mall.show§;这样没问题
匿名对象:mall.show(new Phone()
);不用像上面一样,造个对象,把对象名放进去,直接new Phone(),即这样就为匿名对象的使用

这样后的内存空间
new完的Phone()也在堆空间,有一个地址值

在这里插入图片描述
new Phone().price=1999;
new Phone().showprice();这两种确实只能用一次

但是把匿名对象mall.show(new Phone());赋给另外一个有名的对象 public void show(Phone phone){
}

4.5、自定义数组的工具类

4.6、方法的重载(over load)

4.7、可变个数的形参

方法的形参是可变的
jdk5.0新增

使用场景:可能会出现形参的类型是确定,但是参数的个数不确定。此时,就可以使用可变个数形参的方法。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public vodi print(int…nums){}可变个数形参的方法

测试类
在这里插入图片描述
在这里插入图片描述
再写一个方法是不是跟他构成重载?
可以
在这里插入图片描述
此时
test.print();1111
test.print(1);2222
test.print(1,2);3333
在这里插入图片描述

特例不构成重载
在这里插入图片描述

test.print(new int[]{1,2,3});与public vodi print(int…nums){}一样

在这里插入图片描述public vodi print(int…nums){}这是定义了好几个,如果想在方法中遍历一下,想看变量都是谁,也是for循环遍历
在这里插入图片描述

public vodi print(int[ ]nums){}原来这个想看都有哪些变量,for循环遍历

在这里插入图片描述

在这里插入图片描述
什么时候会有调用方法时,出现方法形类型确定,参数个数不确定?

例:在操作数据库时,会有一个修改数据库的操作时
sql语句
String sql=“update customers set name=?,email=?where id=?”;

public void update(String sql,String…objs);
.png)

方法都是定义好的,
在这里插入图片描述

4.8、方法参数的值传递机制

方法的值传递机制是针对变量赋值操作
一、方法内传递

方法的参数的传递机制:值传递机制(存什么传什么)

变量赋值对方法来讲:
方法中的变量主要有两种,1方法内声明的变量叫局部变量,2方法形参的位置,调方法时给他传实参
在这里插入图片描述
在这里插入图片描述

分两种场景,第一种之前遇到过,数组时遇到过。
1方法内声明的变量的赋值情况
main方法中测试
ValueTransferTest{}
main方法中声明的变量叫局部变量
int n=m;变量赋值

局部变量还可以细分基本数据类型的局部变量、引用数据类型的局部变量
1)基本数据类型的局部变量
在这里插入图片描述
在这里插入图片描述
m的值变了,n的值没有变

栈的main方法对应栈帧,一调main方法加载数据,入栈,声明m,m赋值n,基本数据类型加载完后,没有所谓的地址值一说,存的就是本身的数据,m赋的值是10,即n的值就是10
基本数据类型传的是本身保存的数据值

int n=m;传递的是数据值。布尔类型存的是false,就传false,若存的是true,就传true.double类型存的是你小数点的数,就传小数点的数

2)引用数据类型的局部变量

引用数据类型(数组、对象中的类)
以数组来举例
main方法以栈帧的形式入栈
栈中有个变量ar1,指向堆中new的数组,堆中new的数组有地址值,地址值给了ar1,通过地址值指向了堆空间中的实体
栈中又声明了arr2的变量
int[] arr2=arr1;//传递的是地址值
对于引用数据类型来说,赋值操作,赋的是arr1的地址值
因为引用类型变量存的是地址值,传也会传是地址值,arr2也指向了堆空间中的数组
在这里插入图片描述

在这里插入图片描述
想清楚赋值赋的是什么?内存是什么?
在这里插入图片描述
为什么引用类型数据的变量修改后就修个了值,而基本数据类型的局部变量并未修改值

以对象或者类来举例
栈里是main方法,main方法对应栈帧,加载,入栈,
栈里声明一个变量order1,堆里new了一个order对象,里面有orderId,order对象有一个地址值,将地址值给order1,order1通过地址值指向堆中的order对象,对象调属性赋值1001,还是将order1的地址值赋给order2,所以order2也指向了堆空间中的order对象,进而通过其中一个变量修改属性,属性值都会将变化,通过另一个对象调属性,属性值一定是修改后的
order2.orderId=1002;//传的是地址值
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

二、参数传递
形参
实参
在这里插入图片描述
调方法时,将实参的值传递给形参,出现了赋值操作,这种赋值操作属于什么规则?
在这里插入图片描述

在这里插入图片描述
1)对于基本数据类型的变量来说
main方法进来,对应一个栈帧,加载,入栈

ValueTransferTest1 test=new ValueTransferTest1();test指向堆中的 ValueTransferTest1()对象
main方法中声明了一个m,m为10,
test.method1(m);每一个方法都是栈帧,method方法一调用,入栈,

public void method(int m){
m++;
}m是新的变量

method1方法对应的栈中也有一个变量m,用main方法中的m赋值给method1中的形参

是两个不同的变量
int m=10;
test.method1(m);实参,
上面两个是同一个m
后面这个public void method1(int m){
m++;
}此时为形参,是另一个m

基本数据类型实参赋给形参,传的是数据值,即就是是10

public void method1(int m){
m++;
}method1中++,即method1中的m改为11

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
public void method1(int m){
m++;
}method1方法执行结束,先进后出栈,main方法后出栈,就只剩main方法中的m
在这里插入图片描述
再去打印m,肯定是main方法中,即为10

2)对于引用数据类型的变量来说
定义一个类
在这里插入图片描述

再定义一个方法
在这里插入图片描述
main方法中实例化类
在这里插入图片描述

在这里插入图片描述

为此时p的age是多少11
内存图
main进来一个栈帧,加载,进行入栈,栈中声明局部变量p,堆中有一个对象,对象有属性age,默认值是0,堆中的person对象有地址值,person对象将地址值给p1,p1通过地址值指向person对象,通过p1.age将原先默认值改成10,

test.method2(p);只要新方法就会有一个栈帧,入栈,声明一个变量p,将实参p的地址值赋给形参p的地址值,最后实参指向person对象,
进而在public void method2(Person p){
p.age++;
}
person对象中的age就为10
public void method2执行完后,先进后出,弹出栈
再调main方法中的p.age就为11
在这里插入图片描述

4.9、 递归 (recursion) 方法

5、类的成员之三:构造器(构造方法、constructor)

5.1 、构造器的理解

构造器是常用的结构
一个类中一定会有构造器是正确的

先写一个Person类
在这里插入图片描述
再写一个测试
测试会写创建类的对象
对象再去调属性、调方法
若使用封装性,就不直接访问属性,

在这里插入图片描述

Person person=new Person();这就是构造器

Person左边是类
new Person()构造器
构造器是类的成员

抽象类,抽象类不能造对象,但是有构造器

5.2 、构造器的作用

作用1:搭配new关键字,创建类的对象
作用2:在创建对象同时,可以给对象相关属性赋值

5.3 、构造器的使用说明

1)构造器声明的格式:权限修饰符 类名(形参列表){}
2)创建类后,在没有显示提供任何构造器的情况下,系统会默认提供一个空参的构造器,且构造器的权限与类的声明的权限相同
3)一旦类中显示声明了构造器,则系统就不再提供默认的空参构造器。
4)一个类中可以声明多个构造器,彼此之间构成重载。

Person person=new Person() 其实就是类中的空参构造器public Person(){
}

在这里插入图片描述
在这里插入图片描述
显示声明其他构造器
public Person(int n){
age=n;

}构造器造对象且将类中的age属性赋值

一旦在类中显示声明了构造器,就不会再提供无参构造器,若需要再用就要显示的提供无参构造器
在这里插入图片描述
在这里插入图片描述

在类中可以声明多个构造器,彼此之间构成重载
构造器可以重载吗?可以

构造器也可以叫成构造方法

Scanner sc=new Scanner(System.in);右边就是有参的构造器

package com.zhou.java;

public class PersonTest {


    public static void main(String[] args) {

        Person person = new Person();//左边是类,右边是构造器,其实就是Person类中的空参构造器
        person.eat();


        Person person1 = new Person("zhangsan", 2);
        System.out.println(person1.age);

    }


    static class Person {
        String name;
        int age;

        public Person() {

        }


        public Person(String name) {
            this.name = name;


        }


        public Person(int age) {
            this.age = age;

        }

        public Person(String name, int age) {
            this.name = name;
            this.age = age;

        }


        public void eat() {
            System.out.println("人吃饭");

        }

        public void sleep(int hour) {
            System.out.println("每天睡眠" + hour + "小时");
        }

    }


}

在这里插入图片描述

5.4、总结属性赋值的过程

属性可以在哪些地方进行赋值

总结 : 属性赋值的先后顺序
① 默认初始化值;
② 显式初始化;
③ 构造器中赋值;
④ 通过 " 对象 . 方法 " 或 “对象 . 属性”的方式,赋值
以上操作的先后顺序:① - ② - ③ - ④

String name;
int age;
回头造对象考虑这两个值是多少,就需要看哪些地方可以赋值
没有封装性就对象 . 属性”

先不赋值
在这里插入图片描述
User u = new User(); 此时的构造器也是默认的,也不涉及在构造器中对属性进行赋值,此时age默认值为0

package com.zhou.java;

public class UserTest {

    public static void main(String[] args) {
        User user = new User();//此时的构造器是默认的,不涉及构造器中对属性进行赋值

        System.out.println(user.age);


    }
    }
 class User{

       String name;
       int age;

    }

在这里插入图片描述

将age赋值为1时
在这里插入图片描述
age变成1,只能说明显示赋值是在默认赋值的后面
在这里插入图片描述

写构造器,再调构造器,

public User(){
}
public User(int a){
age = a;
}
User u1 = new User(2); //此时构造器会给属性赋值

显示也会赋值
调System.out.println(u1.age);说明2在后面,将1覆盖调了

package com.zhou.java;

public class UserTest {

    public static void main(String[] args) {
        User user = new User();//此时的构造器是默认的,不涉及构造器中对属性进行赋值

        System.out.println(user.age);
        User user2 = new User(2);

        System.out.println(user2.age);
    }
}

class User {

    String name;
    int age = 1;


    public User() {


    }

    public User(int age) {
        this.age = age;

    }

}

再u1.setAge(3);3,说明2将2覆盖调了
在这里插入图片描述
在四个操作中,对象的值到底是多少,其实是从后往前看,主要取决于后面,关键看方法是否调,再看构造器,构造器没有,再看显示赋值

123从对象出生到死亡只执行过一次,对象出生之前的操作,123都习惯叫初始化

5.5、 JavaBean 的使用

JavaBean 是一种 Java 语言写成的可重用组件。
所谓 javaBean,是指符合如下标准的 Java 类:
有公共的类,有无参的公共构造器、有属性且有get、set方法

public class Customer {
}
此时系统默认会自动提供一个无参构造器,权限是看类的权限,若类的权限是public,默认提供的无参构造器也是public的,系统提供的默认无参构造器是跟类的权限相同

数据库的数据展示在页面,数据库的数据其实就是一个类,就可以设计成javabean

提供无参构造器是为了方便造对象,为什么给类提供一个空参的构造器?涉及到后面造对象时除了new方式造对象,也可以通过反射造对象,反射造对象时都是用的是空参构造器

package com.zhou.java;

public class JavaBean {
    
    public class Customer {
        private int age;
        private String name;


        public Customer() {


        }

        public void setAge(int age) {
            this.age = age;


        }

        public int getAge() {
            return age;


        }

        public String getName() {

            return name;
        }


    }
}

5.6、 UML 类图

表示 public 类型,- 表示 private 类型,# 表示 protected 类型
方法的写法 : 方法的类型 (+、-) 方法名 ( 参数名:参数类型 ):返回值类型
在这里插入图片描述

6、 面向对象特征之一:封装与隐藏

6.1、 封装性的理解

一、封装性的引入与体现
为什么需要封装?封装的作用和含义?
我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗?有必要碰电动机吗?我要开车

二、程序设计追求“高内聚,低耦合”。
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
低耦合:仅对外暴露少量的方法用于使用。
高内聚低耦合:类的内部数据操作细节自己完成,不允许外部干涉;说白了其实就是封装起来了,怎么实现不对外暴露,其实就是使用权限修饰符,通过权限修饰符将权限放到足够小,小到外面的用户看不到里面的方法,就相当于不对外暴,外界需要用什么,就对外暴露什么.

三、隐藏对象内部的复杂性,只对外公开简单的接口(api)。
便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

四、问题的引入:
当我们创建一个类的对象以后,我们可以通过 " 对象 . 属性 " 的方式,对对象的属性进行赋值。这里,赋值操作要受到属性的数据类型和存储范围的制约。但除此之外,没有其他制约条件。但是,实际问题中,我们往往需要给属性赋值加入额外限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行条件的添加。比如说,setLegs 同时,我们需要避免用户再使用“对象 . 属性”的方式对属性进行赋值。则需要将属性声明为私有的 (private)
–》此时,针对于属性就体现了封装性。

五、封装性的体现:
我们将类的属性私有化 (private), 同时 , 提供公共的 (public) 方法来获
取 (getXxx) 和设置 (setXxx)属性。

拓展:封装性的体现:① 如上 ② 单例模式 ③ 不对外暴露的私有方法

class Animal{
String name;
private int age;
private int legs; // 腿的个数
}
public void eat(){
System.out.println(" 动物进食 "); }

测试
动物实列化
Animal a = new Animal();
a.name = " 大黄 ";

a.legs = -4;从实际问题出发,是不能赋值为负数

实际开发中,有一些限制,在属性声明时限制是有些困难

怎么给llegs加限制,使得legs是正偶数,只能考虑方法,提供一个方法,专门给属性leg赋值
// 对于属性的设置
public void setLegs(int l){
if(l >= 0 && l % 2 == 0){
legs = l;
}else{
legs = 0;或者抛出一个异常
} }

public static void main(String[] args) {
a.setLegs(6);
a.setLegs(-6);

咱们提供了一个方法,让用户调方法进行赋值,但是还是可以进行调a.legs = -4,这样还是避免不了用户去调,除了告诉用户我们可以将他设置成限制还要让方法j禁掉(一方面通过方法写限制条件给属性赋值,同时给直接调属性的方式直接禁用)
怎么禁用:就是通过权限修饰符限制

将legs修饰为private
在这里插入图片描述

一方面能够去赋值,另一方面直接将调用属性的事儿禁用,此时就能达到对属性实现了封装,即属性就未对外进行暴露

当去造对象时Animal a = new Animal();
堆空间会加载对象的属性,一定会有legs属性,只不过被隐藏

封装性的体现

平时调属性时,实际体现了两方面的调用,一方面是赋值,另一方面体现为调用
System.out.println(a.name);此时并没有在赋值,只是看看值是多少

因为legs变成私有,赋值可以,但是调用腿有几个却并不行
还提供了获取属性值的操作
在这里插入图片描述

package com.zhou.java;

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal = new Animal();

        animal.name = "大黄";
       // animal.legs = 6;
      //  animal.legs = -4;//从实际问题出发,是不能赋值为负数
      //  animal.setLegs(6);
        animal.setLegs(-4);

        System.out.println(animal.getLegs());


    }


}

class Animal {
    String name;
    int age;
    private   int legs;


    public void eat() {

        System.out.println("动物进食");
    }


    public void setLegs(int legs) {
        if (legs >= 0 && legs % 2 == 0) {
            this.legs = legs;

        }
        legs = 0;

    }


    public int getLegs(){
        return legs;

    }

}

当把属性私有后,体现两方面,1是对属性的set,2对属性的get

6.2、 四种权限修饰符的理解与测试

在这里插入图片描述

封装性的体现,需要权限修饰符来配合。
1)Java 规定的 4 种权限:( 从小到大排序 )private、缺省、protected、
public。
2)四种权限用来修饰类及类的内部结构:属性、方法、构造器、内部类。
3)具体的,4 种权限都可以用来修饰类的内部结构:属性、方法、构造器、
内部类,代码块不行。
注:修饰类的话,只能使用:缺省、public。
总结封装性:Java 提供了 4 中权限修饰符来修饰类积累的内部结构,
体现类及类的内部结构的可见性的方法。
在这里插入图片描述
方法内去调属性
类内部可以使用

package com.zhou.java;

public class Order {
    private int orderPrivate;
    int orderDefault;
    public int orderPublic;


    private void methodPrivate() {
        orderPrivate = 1;

        orderDefault = 2;
        orderPublic = 3;

    }


    private void methodDefault() {
        orderPrivate = 1;

        orderDefault = 2;
        orderPublic = 3;

    }


    private void methodPublic() {
        orderPrivate = 1;

        orderDefault = 2;
        orderPublic = 3;

    }

}

出了这个Order类,在OrderTest这个类中,同一个包中的另外一个类里
在这里插入图片描述

orderPublic = 2;肯定不能调,此类中又没有定义Order类中的结构
在这里插入图片描述
调用还是要通过类的对象调用
创建当前类的对象,Order order = new Order();
order.orderPublic = 2;

	//order.orderPrivate = 3; 出了 Order 类之后,私有的结构、结构就不可调用了//The field Order.orderPrivate is not visible

在这里插入图片描述
再弄一个包
在这里插入图片描述

测试
在这里插入图片描述
在这里插入图片描述

public同一个包下可以用
在com.atgui.java包下的public class Order改成缺省
class order
缺省只能在同一个包下使用
报错
在这里插入图片描述
形象的理解
先只考虑类内部的结构
在这里插入图片描述
体会四种不同的权限修饰符

public class Order{

}
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.java.zhou;

public class Order {
    private int orderPrivate;
    int orderDefault;
    protected  int orderProtected;
    public int orderPublic;


    private void methodPrivate(){

        orderPrivate=1;
        orderDefault=2;
        orderProtected=3;
        orderPublic=4;
    }

  void methodDefault(){

        orderPrivate=1;
        orderDefault=2;
        orderProtected=3;
        orderPublic=4;
    }



    protected void methodProtected(){
        orderPrivate=1;
        orderDefault=2;
        orderProtected=3;
        orderPublic=4;

    }

    public void methodpublic(){
        orderPrivate=1;
        orderDefault=2;
        orderProtected=3;
        orderPublic=4;

    }

}

同包中其他类
在这里插入图片描述

package com.java.zhou;

public class OrderTest {
    public static void main(String[] args) {
        Order order = new Order();
        order.orderDefault=1;
        order.orderDefault=2;
        order.orderPublic=3;
        
        order.methodDefault();
        order.methodProtected();
        order.methodpublic();
        //同一个包中的不同类,不可调用Order类中的私有属性方法
     /*order.orderPrivate=3;
     order.methodPrivate();*/
        
        
    }
    
   

}

同一个包中不是父子类关系,都可以用,是子类那就更可以用。

不同包中但是类是其子类
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

package com.zhou.exer;

import com.zhou.java.Order;

public class OrderSub extends Order {
  public void method(){
      
      orderProtected=1;
      orderPublic=1;
      
      methodProtected();
      methodPublic();
      //不同包中的子类,不可调用Order类中的为private、缺省的属性方法
      /*orderPrivate=1;
      orderDefault=1;

      methodPrivate();
      methodDefault();*/
      
  }
    
}

不同包中不是父子类关系

在这里插入图片描述
package com.zhou.exer;

import com.zhou.java.Order;

public class orderTest1 {

    public static void main(String[] args) {
        Order order = new Order();
        order.orderPublic=1;
        order.methodPublic();



        //不同包中普通类(非子类),要使用Order,不可以调用private,public、defaut方法属性
        /*orderPrivate=1;
      orderDefault=1;
      orderProtected=2;

      methodPrivate();
      methodDefault();
       methodProtected()*/

    }


}

在其他类中想要用Order类,都需要造对象
在这里插入图片描述

package com.zhou.exer;

import com.zhou.java.Order;

public class orderTest1 {

    public static void main(String[] args) {
        Order order = new Order();
        order.methodPublic();
       /* order.orderPublic=1;
        order.methodPublic();*/


        //不同包中普通类(非子类),要使用Order,不可以调用private,public、defaut方法属性
        /*orderPrivate=1;
      orderDefault=1;
      orderProtected=2;

      methodPrivate();
      methodDefault();
       methodProtected()*/

    }


    public void Order(Order order) {


        order.methodPublic();
       /* order.orderPublic=1;
        order.methodPublic();*/


        //不同包中普通类(非子类),要使用Order,不可以调用private,public、defaut方法属性
        /*orderPrivate=1;
      orderDefault=1;
      orderProtected=2;

      methodPrivate();
      methodDefault();
       methodProtected()*/
    }


}

7、 关键字:this

7.1 、this 调用属性、方法、构造器

this是什么?this为什么要用它?怎么用this?

1)this用来修饰调用:属性、方法、构造器

2)this 修饰属性和方法 :
this理解为当前对象或当前正在创建的对象
在类的方法中,我们可以使用 "this. 属性 " 或 "this. 方法 " 的方式,调用当前对象属性或方法。通常情况下,我们都选择省略“this.”。特殊情况下,如果方法的形参和类的属性同名,我们必须显式的使用 "this. 变量 " 的方式,表明此变量是属性,而非形参。
在类的构造器中,我们可以使用 "this. 属性 " 或 "this. 方法 " 的方式,调用正在创建的对象属性和方法。
但是,通常情况下,我们都选择省略“this.”。特殊情况下,如果构造器的形参和类的属性同名,我们必须显式的使用 "this. 变量 " 的方式,表明此变量是属性,而非形参。
3)this 调用构造器
① 我们可以在类的构造器中,显式的使用 " this( 形参列表 ) " 的方式,调用本类中重载的其他的构造器!② 构造器中不能通过 "this ( 形参列表 ) " 的方式调用自己。③ 如果一个类中有 n 个构造器,则最多有 n -1 个构造器中使用了"this ( 形参列表 ) "。④ 规定: " this( 形参列表 ) " 必须声明在类的构造器的首行!⑤ 在类的一个构造器中,最多只能声明一个 “this( 形参列表 )”,用来调用其他构造器。

目前属性、方法、构造器三个结构

封装加个private权限
private String name;
private int age;
class Person{
private String name;
private int age;

为了方便在类外调用和设置属性,提供get和set方法
public void setNmea(String n){/
this.name = n;
}
public String getName(){
return this.name;
}
public void setAge(int m){
this.age =m;
}
public int getAge(){
return this.age;
}

测试一下,在main方法测试
public static void main(String[] args) {
Person p1 = new Person();//空参构造器

set方法都写形参,形参的意义是给属性赋值
形参声明时只是标识符,标识符需要见名识意
public void setNmea(String name){//就是给同名的name属性赋值
public void setNmea(String name){
name=name;
}

public void setAge(int age){
age=age;
}

结果却是0

age=age;怎么区分前面是属性,后面是形参
就可以引入this,表示当前对象
调属性,方法都是点
this.age=age;

为啥要加this,是因为属性和形参重名

此例子中p1.setAge();当前对象为p1,即就是this就是p1

先有类后有对象,代码也是先写类,后写对象

两个方法
public void eat(){
System.out.println(" 人吃饭 “);
}
public void study(){
System.out.println(” 学习 ");
}

方法内可以调方法
public void eat(){
System.out.println(" 人吃饭 ");
study();//此处也省略了this
}

main方法调eat()
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();

在类的构造器中,我们可以使用 "this. 属性 " 或 "this. 方法 " 的方式。
public Person(String name){
this();
this.name = name;//此时的this不能叫当前对象的属性,可以叫当前正在创建的对象的属性
}
public Person(){
this.eat();//当前正在创建对象的方法

	System.out.println(info);

}

this 调用构造器

困扰:代码冗余
解决方法:
构造器里调方法1:把冗余代码封装在方法中
方法2:this调构造器
调空参构造器就直接this();

调用其他的构造器!
public Person(){
this()//这样是不允许的
this()调用其他的构造器!

}

package com.zhou.java;

public class PersonTest {
    public static void main(String[] args) {
        Person person1 = new Person();

        person1.setAge(1);
        System.out.println(person1.getAge());

        person1.eat();



        System.out.println("==========");

        Person jerry = new Person(20, "jerry");
        System.out.println(jerry.getAge());


    }





    static class Person{
        private int age;
        private String name;



        public Person() {




                this.age=age;//此时不能叫当前对象的属性,可以叫当前正在创建的对象的属性
                this.eat();//当前正在创建对象的方法
                String info = "Person 初始化时,需要考虑如下的 1,2,3,4...( 共 40 行代码 )";
            System.out.println(info);

            }




        public Person(int age){
             this();

            this.age=age;

        }


        public Person(String name){
            this();
           name= this.name;

        }

        public Person(int age,String name){
            this(age);
            this.name=name;
            this.age=age;

        }


        public void setAge(int age){
       //  age=age;
            this.age=age;

        }


        public void setName(String name){

            this.name=name;
        }

        public int getAge(){

            return age;
        }
        public String getName(){
            return name;
        }

      public void eat(){
          System.out.println("人吃饭");
        study();//此处省略了this


      }

        public void study() {
            System.out.println("学习");
        }


    }


}

在这里插入图片描述

后续造一个类时,提供多个重载构造器时,可以考虑使用this方式,当一个结构写了逻辑,另一个构造器也要写这些逻辑时就可以用到此方式

hashMap()看成是一个类,干什么的暂时不用管
他也有一个构造器
在这里插入图片描述

java.util---- 包含一些实用工具类,像Scanner、Arrays都是属于util下的类

java.awt显示客户端界面之类的
用java语言也可以写桌面应用
需要出具体的客户端就需要用到awt’,不过暂时都不用了
现在都是访问浏览器来访问后台java

8、关键字:package、import

8.1 、关键字—package

Java语言赋予特殊含义的字符串或单词称为关键字。

1)为啥要引入包
为了更好的实现项目中类的管理,提供包的概念。
2)使用
① 使用 package 声明类或接口所属的包,声明在源文件的首行。
② 包:属于标识符,遵循标识符的命名规则、规范 " 见名知意 "。命名规则(必须要遵守,大小写,下划线,数字不能开头等)规范(包名都是小写)
③ 每“.”一次 , 就代表一层文件目录。

补充 : 同一个包下,不能命名同名接口或同名类。
不同包下,可以命名同名的接口、类。
后面使用的xml,也要先声明版本号,字符集之类的,此时必须在首行

3)JDK 中主要的包介绍
1.java.lang---- 包 含 一 些 Java 语 言 的 核 心 类, 如 String、Math、Integer、System 和 Thread,提供常用功能
2.java.net---- 包含执行与网络相关的操作的类和接口。
3.java.io---- 包含能提供多种输入 / 输出功能的类。
4.java.util— 包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。
5.java.text---- 包含了一些 java 格式化相关的类
6.java.sql---- 包含了 java 进行 JDBC 数据库编程的相关类 / 接口
7.java.awt---- 包含了构成抽象窗口工具集(abstractwindowtoolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面 (GUI)。B/S C/S

8.2、 MVC 设计模式

创建一个工程时会有很多类,类通过包的方式管理。管理的话就有一种模式:mvc设计模式

MVC 是常用的设计模式之一,将整个程序/项目分为三个层次:视图模型层,控制器层,数据模型层。这种将程序输入输出、数据处理,以及数据的展示分离开来的设计模式使程序结构变的灵活而且清晰,同时也描述了程序各个对象间的通信方式,降低了程序的耦合性。

model表示具体的某个项目或者公司的域名倒序
模型层 model 主要处理数据

数据对象封装 model.bean/domain
数据库操作类 model.dao
数据库 model.db

数据库交互出问题就差不多是模型层的包下 model.dao,数据库 model.db

视图层 view 显示数据

相关工具类 view.utils
自定义 view view,ui

控制层 controller 处理业务逻辑

应用界面相关 controller.activity
存放 fragment controller.fragment
显示列表的适配器 controller.adapter
服务相关的 controller.service
抽取的基类 controller.base

8.3、 关键字—import

最初使用import是Scanner()

import 关键字的作用
import: 导入
1)在源文件中显式的使用 import 结构导入指定包下的类、接口。
2)声明在包的声明和类的声明之间。
3) 如果需要导入多个结构,则并列写出即可。
4)可以使用 “xxx.*” 的方式 , 表示可以导入 xxx 包下的所有结构。
5)如果导入的类或接口是 java.lang 包下的,或者是当前包下的,则可以省略此 import 语句。
6.)如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类。
7.)如果已经导入 java.a 包下的类。那么如果需要使用 a 包的子包下的
类的话,仍然需要导入。
8)import static 组合的使用:调用指定类或接口下的静态的属性或方法。

public static void main(String[] args)

System.out.println(“hello”);String ,system都是类,没有导包,这两个是核心包(使用频繁)定义在lang包下的类或接口,不用在导,默认就可以用
当前包下的

实际开发中还是会出现的问题,如
如果在代码中使用不同包下的同名的类。那么就需要使用类的全类
名的方式指明调用的是哪个类。类的全类名

在这里插入图片描述

如果已经导入 java.a 包下的类。那么如果需要使用 a 包的子包下的
类的话,仍然需要导入。
com.atguigu.java2.java3称为 java2下的子包
在com.atguigu.java2.java3定义一个Dog类
在这里插入图片描述
在这里插入图片描述
在com.atguigu.java2下用dog需要导包吗?需要导包

static 组合的使用:调用指定类或接口下的静态的属性

System.out.println(“hello”);
System是一个类
out是一个属性,是System类的静态结构,是类中定义的一个属性
在这里插入图片描述
还可以这么写
import static java.lang.System.*;表示可以调用System类下的静态结构
然后System就可以删掉了
在这里插入图片描述
在这里插入图片描述
out就是用的System下的静态 的结构 结构可以是属性或方法
在这里插入图片描述

在这里插入图片描述
import的落脚点是类或接口
import static是落脚点是属性或方法

9、练习

9.1、this练习

this练习1
在这里插入图片描述

girls

public void marry(Boy boy){
System.out.println(" 我想嫁给 " + boy.getName());
//我想娶
boy.marry(this);需要一个变量,需要girl类
}

compare
对象跟对象怎么比较大小,根据对象的属性比较大小
当前对象是指调方法的对象

else if(compare < 0){
System.out.println(girl1.getName() + " 大 ");//形参大

package com.zhou.exer;

public class ThisTest {


    public static void main(String[] args) {

        Boy boy = new Boy(21, "罗密欧");
        boy.shout();


        Girl girl = new Girl(18, "朱丽叶");
        girl.marry(boy);
        boy.marry(girl);

        Girl girl1 = new Girl(19, "祝英台");
        int compare = girl.compare(girl1);
        if(compare>0){

            System.out.println(girl.getName()+"大");
        }else if(compare<0){
            System.out.println(girl.getName()+"小");
        }else {

            System.out.println("一样的");
        }

    }

    static class Boy {
        private int age;
        private String name;


        Boy() {


        }

        Boy(int age) {
            this.age = age;


        }

        Boy(String name) {
            this.name = name;

        }

        Boy(int age, String name) {
            this.name = name;
            this.age = age;


        }

        public void setAge(int age) {
            this.age = age;


        }

        public void setName(String name) {
            this.name = name;

        }

        public int getAge() {
            return age;
        }

        public String getName() {
            return name;
        }

        public void marry(Girl girl) {
            System.out.println("我想娶" + girl.getName());
        }


        public void shout() {

            if (this.age >= 22) {
                System.out.println("可以考虑结婚");


            } else {
                System.out.println("好好学习");
            }
        }
    }

    static class Girl {
        private int age;
        private String name;

        public Girl(int age, String name) {
            this.age = age;
            this.name = name;


        }

        public void setName(String name) {
            this.name = name;

        }

        public String getName() {
            return name;
        }


        public void marry(Boy boy) {

            System.out.println("我想嫁给" + boy.getName());
        }


        public int compare(Girl girl) {
            //		if(this.age >girl.age){
// return 1;
//		}else if(this.age < girl.age){
//			return -1;
// }else{
//			return 0;
// }

            return this.age - girl.age;
        }


    }


}

在这里插入图片描述

this练习2

9.2、练习

构造器的作用是什么?使用中有哪些注意点(>=3点)
关于类的属性的赋值,有几种赋值的方式,谈谈赋值的先后顺序
this关键字可以用来调用哪些结构,简单说明一下其使用
java中目前学习涉及到的四种权限修饰符是哪些?说明各自的权限范围
创建Circle类,提供私有的radius属性,提供相应的get和set方法,提供求圆面积的方法

9.3、构造器练习

构造器练习1
在这里插入图片描述

在这里插入图片描述
测试类
ctrl+p可以看到小括号里的参数
在这里插入图片描述
在这里插入图片描述
对三个属性做了初始化,但是major没有做初始化,String初始化的值即为null
在这里插入图片描述

package com.zhou.exer;

public class ConstructorTest {

    public static void main(String[] args) {
        Student student = new Student("zhangsan", 68, "beijindaxue", "心理学");
        System.out.println(student.getInfo());
        Student student2 = new Student("zhangsan", 68, "beijindaxue");
        System.out.println(student2.getInfo());

    }

    public static class Student {
        String name;
        int age;
        String school;
        String major;

        public Student(String n, int a) {
            name = n;
            age = a;

        }

        public Student(String n, int a, String s) {
            name = n;
            age = a;
            school = s;

        }

        public Student(String n, int a, String s, String m) {
            name = n;
            age = a;
            major = m;

        }


        public String getInfo() {

            return "name=" + name + ",age=" + age + ",school" + school + ",major=" + major;
        }


    }


}

在这里插入图片描述

构造器练习2
在这里插入图片描述
在这里插入图片描述

public double findArea(){}此时方法不用形参,调方法是一个三角形,三角形有底边长高,直接在里边用底边长高就行
public double findArea(){
return base*hight/2
}

测试类

public static void main( String[]args){
TriAngle triangle= new TriAngle();此时属性是默认值的
此时面积为0

在这里插入图片描述
在这里插入图片描述

}

创建TriAngle 的其他实例
通过构造器的方式给对象属性赋值
在这里插入图片描述

package com.zhou.exer;

public class TriAngleTest {
    public static void main(String[] args) {
        TriAngle triAngle = new TriAngle();
        System.out.println(triAngle.findArea());//此时属性是默认值,此时面积为0

        triAngle.setBase(3);
        triAngle.setHeight(4);

        System.out.println(triAngle.findArea());


        TriAngle triAngle1 = new TriAngle(2.5, 5.6);
        System.out.println(triAngle1.getBase());
        System.out.println(triAngle1.getHeight());
        System.out.println(triAngle1.findArea());

    }

}

class TriAngle {
    private double base;
    private double height;

    public TriAngle() {
    }

    public TriAngle(double height, double base) {
        this.height = height;
        this.base = base;
    }

    public void setBase(double base) {

        this.base = base;

    }


    public void setHeight(double height) {

        this.height = height;

    }


    public double getBase() {
        return base;
    }


    public double getHeight() {

        return height;
    }

    public double findArea() {
        return base * height / 2;

    }


}

在这里插入图片描述

构造器练习3
在这里插入图片描述

在这里插入图片描述

9.4、封装性的练习

在这里插入图片描述

9.5重载练习

在这里插入图片描述

9.6可变个数形参的方法练习

在这里插入图片描述

9.7值传递机制练习

值传递机制练习1
在这里插入图片描述
在这里插入图片描述
将交换的功能(蓝色圈住的代码)封装在一个方法中?

public void swap(int m,int n){
int temp=m;
m=n;
n=temp;

}
在这里插入图片描述
调方法
调方法前需要创建对象
在这里插入图片描述

在这里插入图片描述
最后结果却没有变,为什么?

在这里插入图片描述
值传递机制练习2

在这里插入图片描述
在这里插入图片描述

问m与n的值是否更换?
更换了

在这里插入图片描述
值传递机制练习3
在这里插入图片描述
只要方法涉及到形参,调方法时有实参,都是值传递机制

package com.zhou.exer;



public class PassObject {


    public static void main(String[] args) {

        PassObject passObject = new PassObject();
        Circle c = new Circle();
        passObject.printAreas(c,5);
        System.out.println("now radius is"+c.radius);



    }


    public void printAreas(Circle c, int time) {
        System.out.println("Radiud\t\tArea");
        int i = 1;
        for (; i <= time; i++) {
            c.radius = i;
            System.out.println(c.radius+"\t\t\t"+c.findArea());

        }
        c.radius = i;
    }

}


class Circle {
            double radius;


            public double findArea() {

                return Math.PI * radius * radius;
            }
        }

在这里插入图片描述

值传递机制练习4
在这里插入图片描述

10、面试题

谈谈你对面向对象三大特征的理解
第一个封装性
我们将类的属性私有化 (private), 同时 , 提供公共的 (public) 方法来获取 (getXxx) 和设置 (setXxx),这是封装性的体现之一,并不是就是封装性。
体现2:

11、项目二

11.1目的

模拟实现一个基于文本界面的《客户信息管理软件》
进一步掌握编程技巧和调试技巧,熟悉面向对象编程
主要涉及以下知识点:
类结构的使用:属性、方法及构造器
对象的创建与使用
类的封装性
声明和使用数组
数组对的插入、删除和替换
关键字的使用:this

11.2项目架构

在这里插入图片描述

11.3项目需求说明书

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.4三层模式设计

包体现了mvc的涉及模式

Customer 为实体类,用来封装客户信息。可以声明JavaBean,就可以放在bean包下,就相当于是model层

CustomerList 为 Customer 对象的管理模块相当于mvc的controller具体处理业务 看到的数据都是从控制层从数据库里调完装配出来,装配这个事儿就是控制台来做
增删改查数组中的业务逻辑核心都是由控制层来做
服务相关的都是service

跟用户交互视图展示,就是mvc中的视图层CustomerView 为主模块,负责菜单的显示和处理用户操作,客户选择1234

在这里插入图片描述

11.5工具类CMUtility代码及说明

除了以上的类,还提供了一个工具类,CMUtility具体属于mvc那一层,就需要看具体为谁服务,如是给用户界面服务就是视图层view

static暂时忽略,特点是直接通过类就可以调用,类似于Array,Math.radam()功能差不多主要关注此工具类的方法都是干啥用的
r readChar()性别多少,性别是读字符获取

修改时用到的readChar(char defaultValue)与readChar()构成重载,修改的时候传的还是原来的性别,若不想改直接回车,若用户没有输入,就拿形参填充,默认值返回public static char readChar(char defaultValue)
public static int readInt()年龄public static int readInt(int defaultValue)修改年龄时用到的

姓名、电话

11.6类的设计

第一步:Customer 类的设计

提供各属性的 get / set 方法,权限都比较小了,private
满足javabean,类是公共的,提供了公共的无参构造器,提供了属性以及get,set方法这就是javabean方便在后续业务中进行操作

第二步:CustomerList 类的设计里面造一个数组
对customer进行增删改查操作的功能

属性有两个私有化

Customer[] customers;引用别的包时都需要导入

public CustomerList(int totalCustomer) {//构造器,初始化数组,告诉数组多长、用来设置数组存储的最大值
customers = new Customer[totalCustomer];//创建customer对象时,将数组进行初始化,不知元素是谁,就用动态初始化
操作数组前进行初始化,无论是显式初始化还是构造器都可以,此处选择的是在构造器中初始化
}

private int total = 0;不写0也是0,写0也是0,一样

public boolean addCustomer(Customer customer) {
if(total >= customers.length) {满了就会添加失败
就先判断是否满,已经存了total个
return false;
}

customers[total] = customer;首次调用customer,total就是0
total++;
return true;

怎么算修改成功怎么算修改失败,跟index有关,index写的不靠谱就失败

customers[index] = cust;
内存结构
在这里插入图片描述

cl是栈中是customerlist,右边是堆,堆中有两属性,一个属性是total默认值为0,一个是数组 Customer[] customers(引用类型要么是null,要么是引用地址,声明时没有赋过值,是null,用构造器时就new,new就为新的结构,new了一个新的数组,新的数组的长度是10,往下放,新的数组有地址值,地址值就给了customers
在这里插入图片描述

左边customerlist调方法就能找到右边customers,customers初始化就能找到index的位置,若右边cuntomer已经存了几个人,每个位置都是cuntomer,cuntomer也的是对象,就new了对象
每个对象地址再给了右边的位置,custmer也是引用对象,得new一个对象,存得仍然是地址,修在这里插入图片描述
修改replace相当于是又重新new了一个对象再重新指向他,原来得没有指针指向,就被销毁了
在这里插入图片描述

仍然用原来的对象,只是属性修改,相当于是将对象调出来修改里面的属性也可以

重新传的若是原来的引用地址就只是修改里面原来的东西,取决于customerview怎么写
customerview若是重新new了一个,则就是蓝色的方式
若用的还是原来的对象,只是重新set了某一个属性,传来还是原来的地址,还是原来红色的对象

删除
在这里插入图片描述

想删除某一个时,不能将删除的那一个置为null,因为数组是有序的,删除前面时,后面一个需要覆盖前面一个,将最后一个置为null
在这里插入图片描述

customers[i] = customers[i + 1];后一个位置赋给前一个位置,只需保证 customers[i + 1]取到最后一个
i < total - 1不是写customers,而是写total-1

Customer[] getAllCustomer(){
不能直接一来就return customers;因为有很多空
}

custs[i] = customers[i];没有每个对象都赋值,只是赋值了地址值

目前的customers都在堆空间中

原本数组长度为10,存了4个元素,原来的存的都是地址值,指向真实的对象,四个对象,其他为空
在这里插入图片描述

在这里插入图片描述

又造了一个数组,长度就是4,只是把原来地址拿过来,指向的对象仍是原来的对象
在这里插入图片描述

CustomerView 模块
第三步:CustomerView 类的设计
CustomerView 为主模块,负责菜单的显示和处理用户操作
本类封装一下信息:

CustomerList customerlist = new CustomerList(10)数组长度为10

main方法为入口,肯定是在main方法调,程序执行都是从main开始,怎么去调上面功能
先把方法声明出来:执行程序,就先显示界面,意味着先调public void enterMainMenu() 方法,写出他的业务逻辑System.out.println(“\n-------------------- 客户信息管理
软件 --------------------”);
System.out.println(" 1. 添加客户 “);
System.out.println(” 2. 修改客户 “);
System.out.println(” 3. 删除客户 “);
System.out.println(” 4. 客户列表 “);
System.out.println(” 5. 退 出 \n");
System.out.print(" 请选择(1-5):");

当用户选择完1,2,3,4,5只要用户不退出,又会出现此页面在这里插入图片描述
放在循环体中,循环体中没有确定的次数
boolean isFlag = true;
while (isFlag) {

想让他停下,某一时刻改为isFlag = false;应该是退出来做false,执行到5,就需要用户选择char isExit = CMUtility.readConfirmSelection();获取1,2,3,4,5中的某一个字符,只要不是就出不了循环就会一直重新输入
在这里插入图片描述
char menu = CMUtility.readMenuSelection();
得到menu到底是12345中哪一个就需要做分支switch (menu) {
case ‘1’:单引号一定要加,工具类中的是有单引号

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值