面向对象(上)

1.面向对象的三条主线

<1>Java类及类的成员:属性,方法,构造器;代码块,内部类

<2>oop的三大特征:封装性,继承性,多态性

<3>其它关键字

2.类和对象的一些概念

(类:抽象;对象:为某类事物的真实存在的个体)

(类的设计:实质就是类的成员的设计)

2.1属性和方法

·属性=成员变量=field=域、字段

·方法=成员方法=method=函数

创建类的对象=类的实例化=实例化类

2.2类和对象的使用(面向对象思想落地的实现)

step1:创建类,设计类的成员;

step2:创建类的对象;

step3:通过“对象.属性”和“对象.方法”调用对象的结构。

2.3类的访问机制

<1>在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。(例外:static方法访问非static,编译不通过);

<2>在不同类中的访问机制:先创建要访问类的对象,再用对象访问类中定义的成员。

2.4一个例子

假设有一个class A,有如下代码:

A a1=new A();  A a2=new A();  a2=a1; //此时a1和a2指向了同一个地址值,若改变a1的属性值,a2的属性值也会随之改变

2.5对象的创建与使用之内存解析

①内存区域介绍

<1>堆(Heap):存放对象实例;

<2>栈(Stack):存储局部变量等;

<3>方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

②图解举例说明:

 2.6匿名对象

匿名对象:我们创建的对象,没有显示地赋给一个变量名;

特点:匿名对象只能使用一次(下次再定义一个匿名对象,那就是另一个了);

举例:假如show()方法是Phone类中的方法,则可以有new Phone().show();  //这个对象并没有赋给某个变量名

3.加深对自定义类数组的内存解析的理解

4.类的成员之——属性

4.1语法格式

权限修饰符  数据类型  属性名  =  初始化值;

注:常用的权限修饰符有:private,缺省,protected,public

       其他修饰符:static,final等

4.2属性(成员变量)与局部变量的异同点

相同点:语法格式相同;都是先声明,后使用;都有其对应的作用域。

不同点:

属性(成员变量)局部变量
声明的位置直接声明在类中方法内、方法形参、代码块内、构造器内等
权限修饰符privata、public、static、final等不能使用权限修饰符,但可以使用final
初始化值有默认初始化值没有默认初始化值,且必需显式赋值(形参除外)
在内存中加载的位置堆空间(非static)和静态域(static)内栈空间

5.类的成员之——方法

5.1按照有无返回值有无形参的分类

无返回值有返回值
无形参

void 方法名 ()

{}

返回值类型 方法名 ()

{

return 返回值类型的变量或者常量

]

有形参

void 方法名 (形参类型 形参名)

{} 

返回值类型 方法名 (形参类型 形参名)

{

return 返回值类型的变量或者常量

}

5.2方法的声明

格式:   权限修饰符   返回值类型   方法名  (形参列表)

              {方法体}

<1>权限修饰符:public、缺省、protected、private;

<2>返回值类型:有返回值 or 无返回值(见上面的表格);

<3>方法名(属于标识符)→应该要见名知意;

<4>形参列表:可声明0个,1个或多个形参;

<5>方法体:方法功能的体现。

5.3return关键字的使用

<1>使用范围:方法体中;

<2>作用:结束方法;针对于有返回值类型的方法,使用“return 数据”方法;

<3>return关键字后面不可声明执行语句。

5.4方法的使用:

<1>方法使用中,可以调用当前类的属性和方法(也可调用自身,即递归)

<2>方法中定义新的方法

6.再谈方法

6.1方法重载(方法同名不同参)

在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或参数类型不同即可(与返回值类型无关)。

6.2可变个数形参的方法

<1>格式:(数据类型...形参名)

<2>定义:能和任意个实参相匹配的形参

eg:

public void test(String...books)
{
   for(int i=0;i<books.length;i++)
      System.out.println(boos[i]);
}

可以发现,其实还是把它当数组用。

<3>需要注意的问题:

1)可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载,即:

public void test(String...books)和public void test(String[] books)是一样的,不可共存在一个类中。

2)每个方法最多只能声明一个可变个数的形参,且需放到形参列表的最后

eg:public void test(int a,boolean b,double...c){方法体}

3)当需要调用方法时,优先调用确定多个形参的方法,例如:

public void add(int a,int...arr);

public void add(int a,int b,int c);

对于一个调用:test.add(1,2,3);//调用的是add(int a,int b,int c)方法

6.3方法参数的值传递机制

<1>对于方法内变量的赋值

若变量是基本数据类型,此时赋值的是变量保存的数据值;

若变量是引用数据类型,此时赋值的是变量保存的数据的地址值(地址值中也含有变量的数据类型)。

eg:

int m=10;
int n=m;//此时m=10,n=10
n=20;//此时m=10,n=20
//**********************************
int[] a1=new int[2];
int[] a2=new int[2];
a1.[1]=2; // 此时a1为{0,2},a2为{0,0}
a2=a1; //此时a1为{0,2},a2为{0,2}
a2.[0]=1; //此时a1为{1,2},a2为{1,2}

<2>有关实参和形参

1)如果形参为基本数据类型,此时实参赋给形参的是实参真实存储的数据值;

2)如果形参为引用数据类型,此时实参赋给形参的是实参存储数据的地址值。

eg:

class Data
{
    int m;
    int n;
    void swap(Data data) //形参为引用类型
    {
        int temp = data.m;
        data.m = data.n;
        data.n = temp;
    }
}
public class Test
{
    public static void main(String[] args)
    {
            Data data = new Data();
            data.m = 10;
            data.n = 20;
            data.swap(data); //data.m的值变为了20,data.n变为了10
            System.out.println(data.m,data.n);
    }
}

上述代码的内存解析图:

<3>一个例题,囊括了上面说的知识,见代码:

//定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)
// 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
//问题一:打印出3年级(state值为3)的学生信息。
//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
class Student
{
    int number;  //学号
    int state;   //年级
    int score;   //成绩
    public void print()  //打印Student对象的属性信息
    {
        System.out.println("学号:"+number+"\t年级: "+state+"\t成绩:"+score);
    }
    public void swap(Student[] arr,int i,int j)  //交换Student数组的两个元素
    {
        Student t=arr[i];
        arr[i]=arr[j];
        arr[j]=t;
    }
    public void Bubble(Student[] arr) //冒泡法按照Student对象的成绩从小到大排序
    {
        for(int i=0;i<arr.length-1;i++)
            for (int j=0;j<arr.length-1-i;j++)
                if(arr[j].score>arr[j+1].score)
                    swap(arr,j,j+1);
    }
}
public class StudentTest
{
    public static void main(String[] args)
    {
        Student[] arr=new Student[20];
        for(int i=0;i<20;i++)
        {
            //arr[i]=new Student();这一行代码千万不能少
            //因为在声明了自定义类的数组之后,对每一个数组元素的初始化,都要为其new一个对象出来使得指针指向该对象
            //Java语言本身是不提供在自定义类数组声明时候自动创建新对象的方式的
            //卧槽,其实是不是不管这个类是否自定义,在创建完对象数组后都需要new,而String恰好特殊而已吗?
            //找个人问问!!!!!!!!!!!!!!
            arr[i]=new Student();
            arr[i].number=i+1;
            arr[i].state=(int)(Math.random()*6+1);
            arr[i].score=(int)(Math.round(Math.random()*100)); // 四舍五入取整:Math.round(double d),返回值类型long
            if(arr[i].state==3)
                arr[i].print();
        }
        System.out.println("**********************************************");
        Student a=new Student();
        a.Bubble(arr);
        /* 对于上面的两行代码,也可以把Student类中的对应方法加上static,然后这里写成:
        * Student.Bubble(arr);
        */

        for(int i=0;i<arr.length;i++)
            arr[i].print();
    }
}

 6.4递归(recursion):一个方法体内调用它自身

注意:一定要向已知方向递归,否则会变成死循环。

几个递归的例子:


//练习7.1:请用Java写出递归求阶乘(n!)的算法
//**********************************************
public class RecursionTest
{
    public int factorial(int n)
    {
        if(n==1)
            return 1;
        else
            return n*factorial(n-1);
    }
    public static void main(String[] args)
    {
        System.out.println(new RecursionTest().factorial(4));
    }
}
//************************************************
//练习7.2:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0的整数,求f(10)的值。
//************************************************
public class RecursionTest
{
    public int function(int n)
    {
        if(n==0)
            return 1;
        if(n==1)
            return 4;
        else
            return 2*function(n-1)+function(n-2);
    }
    public static void main(String[] args)
    {
        System.out.println(new RecursionTest().function(10));
    }
}
//************************************************
//练习7.3:已知一个数列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值。
public class RecursionTest
{
    public int function(int n)
    {
        if(n==20)
            return 1;
        if(n==21)
            return 4;
        else
            return function(n+2)-2*function(n+1);
    }
    public static void main(String[] args)
    {
        System.out.println(new RecursionTest().function(10));
    }
}

7.面向对象的特征之一——封装与隐藏

7.1封装性的体现

<1>将类的属性xxx私有化(private),同时,提供公共的(public)的方法来获取getXxx()和设置setXxx()属性的值;

<2>不对外暴露的私有的方法;

<3>单例模式(将构造器私有化)→现在还不知道是什么!

7.2封装性的体现需要修饰符来配合

<1>Java规定的四种权限(从小到大):private,缺省,protected,public

<2>四种权限修饰符修饰类的成员时,其他对象对类中该成员的访问权限见下图:

<3>注意:4种修饰符都可以用来修饰类的内部结构:属性、方法、构造器、内部类;但是修饰类的话,只能使用缺省和public(若为缺省的,则该类不能在包外被调用)。

 8.类的成员之——构造器

8.1构造器的作用

创建对象;给对象进行初始化。

8.2构造器定义的格式

权限修饰符 类名(形参列表)

{构造器内部代码}

8.3关于构造器的一些说明

<1>若没有显示地定义类的构造器的话,则系统默认提供一个空参的构造器,一旦显示地定义了类的构造器,系统就不再提供提供默认的空参构造器;

<2>类中定义的多个构造器可构成重载;

<3>子类无法继承父类中的构造器。

9.JavaBean

JavaBean是一种Java语言写成的可重用组件,是指符合一下标准的Java类:

<1>类是公共的→public class 类名;<2>有一个无参的公共的构造器;<3>有属性,且有对应的get()和set()方法。

10.UML类图

11.关键字:this的使用

this可用来修饰属性、方法、构造器。

11.1this修饰属性和方法:this理解为当前对象

<1>在类的方法中,可使用“this.属性”或“this.方法”的方式,调用当前对象的属性或方法,但通常我们都省略“this.”。特殊的,当方法的形参和类的属性同名时,我们必须显示地使用“this.变量”的方式,来表明此变量为属性,而非形参。

<2>在类的构造器中,同上。

11.2this调用构造器

比如存在多个构造器,b构造器想用a构造器中的内容,则需在b构造器中调用a构造器。

是在构造器中调构造器,“this(形参列表)”需声明在首行,是一个构造器内部,最多只能声明一个“this(形参列表)”。

11.3关于this的练习

 以下为代码:其中含有相关注释

public class Account//Account类
{
    private double balance;//账户余额
    public Account(double balance)//构造器
    {
        this.balance=balance;
    }
    public double getBalance()
    {
        return balance;
    }
    public void setBalance(double balance)
    {
        this.balance=balance;
    }
    public void withdraw(double amount)//取钱操作
    {
        if(amount<=balance)
            balance-=amount;
        else
            System.out.println("你想取的钱太多了哦~");
    }
    public void deposit(double amount)//存钱操作
    {
        if(amount<=0)
            System.out.println("你这是在存钱吗?逗我呢!");
        else
            balance+=amount;
    }
    public void show()
    {
        System.out.println("account balance is: "+balance);
    }
}



public class Customer  //Customer类
{
    private String firstName;//名字
    private String lastName;//姓氏
    private Account account;//账户信息(在自定义类中,可以声明其他自定义类类型的属性)
    public Customer(String f,String l)
    {
        firstName=f;
        lastName=l;
    }
    public String getFirstName()
    {
        return firstName;
    }
    public String getLastName()
    {
        return lastName;
    }
    public Account getAccount()
    {
        return account;
    }
    public void setAccount(Account account)
    {
        this.account=account;
    }
    public void show()
    {
        System.out.println("firstname is: "+firstName+", lastname is: "+lastName+",");
        account.show();
    }
}



public class Bank  //Bank类
{
    private Customer[] customers=new Customer[100];//要么在这里(属性声明时)创建数组,要么在构造器中创建数组,千万不能写在方法中,要是写在方法中,就变成了调一次方法,就创建了一个新的数组,根本存储不了之前的数据。
    private int numberOfCustomer;
    public Bank()
    {}
    public void addCustomer(String f,String l)
    {
        Customer cust=new Customer(f,l);
        customers[numberOfCustomer]=cust;
        numberOfCustomer++;
    }
    public int getNumberOfCustomer()
    {
        return numberOfCustomer;
    }
    public Customer getCustomer(int index)
    {
        if(index>=0&&index<numberOfCustomer)
            return customers[index];
        else //这个else还必须得加
            return null;
    }
    public void show()
    {
        for(int i=0;i<numberOfCustomer;i++)
            customers[i].show();
    }
}


public class BankTest   //BankTest测试类
{
    public static void main(String[] args)
    {
        Account acc1=new Account(2000);
        Bank bank1=new Bank();
        bank1.addCustomer("Li","Hua");
        bank1.getCustomer(0).setAccount(acc1);//这种写法叫连续操作
        bank1.getCustomer(0).getAccount().withdraw(1000);//这种写法叫连续操作
        bank1.show();
    }
}

12.关键字:package和import

12.1关键字package的使用

<1>为了更好的实现项目中类的管理,而提供包的概念;

<2>声明在源文件的首行(只是代码的首行,不是非要是第一行,只要前面没有代码就行);

<3>包:属于标识符;

<4>每“.”一次代表一层文件目录;

<5>同一个包下,不能命名同名的接口、类;不同包下可以。

12.2关键字import的使用

<1>在源文件中显式的使用import结构导入指定包下的类、接口;

<2>声明在包的声明和类的声明之间;

<3>可以利用“xxx.*”的方式,导入xxx包下的所有结构(即接口或类);

<4>定义在java.lang包下的类或接口,可省略import;

<5>定义在本包下的类或接口,可省略import;

<6>若在源文件中,使用了不同包下的同名的类,则必须有一个类需要以全类名方式命名;

<7>使用“xxx.*”方式声明可以调用xxx包下的所有结构,但如果使用的是xxx包的子包下的结构,则仍需要显式import该子包;

<8>import static,导入指定类或接口的静态结构:属性或方法;其他的import导入的是包,import static直接导入了某个包下的结构,注意。

13.项目二的实现:(尚硅谷ppt项目二:客户信息管理软件)

13.1需求说明

13.2程序设计结构

 还含有一个工具类CMUtility,提供关于输入的一些操作。

13.3代码:(含有注释)

<1>工具类:CMUtility

public class CMUtility  //工具类
{
    private static Scanner scanner=new Scanner(System.in);
    /**
     从键盘读取要求个数的字符串
     */
    private static String readKeyBoard(int limit,boolean blankReturn)
    //这里boolean变量若为true,表示返回空值也可以接受;为false,则不能接受,需要继续输入
    {
        String line="";
        while(scanner.hasNextLine())
        {
            line=scanner.nextLine();
            if(line.length()==0)
            {
                if(blankReturn) return line;
                else continue;
            }
            if(line.length()<1||line.length()>limit)
            {
            System.out.println("输入长度(不大于"+limit+")错误,请重新输入");
            continue;
            }
              break;
        }
        return line;
    }
    /**
    用于界面菜单的选择。该方法读取键盘,如果用户键入‘1’-‘5’中的任意字符,则返回该字符。
     */
    public static char readMenuSelection()
    {
        char c;
        for(;;)
        {
            String str=readKeyBoard(1,false);
            c=str.charAt(0);
            if(c=='1'||c=='2'||c=='3'||c=='4'||c=='5')
                break;
            else
                System.out.print("你的输入有误,请重新输入:");
        }
        return c;
    }
    /**
     键入一个字符,并将其作为返回值。
     */
    public static char readChar()
    {
        String str=readKeyBoard(1,false);
        return str.charAt(0);
    }
    /**
    键入一个字符,并将其作为返回值。
     若用户不输入字符而直接回车,方法将以defaultValue作为返回值。
     */
    public static char readChar(char defaultValue)
    {
        String str=readKeyBoard(1,true);
        return (str.length()==0)? defaultValue :str.charAt(0);
    }
    /**
     从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
     */
    public static int readInt()
    {
        int n;
        for(;;)
        {
            String str=readKeyBoard(2,false);
            try
            {
                n=Integer.parseInt(str);
                break;
            }
            catch(NumberFormatException e)
            {
                System.out.println("数字输入错误,请重新输入:");
            }
        }
        return n;
    }
    /**
     从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
     若用户不键入字符而直接回车,方法将以defaultValue作为返回值。
     */
    public static int readInt(int defaultValue)
    {
        int n;
        for(;;)
        {
            String str=readKeyBoard(2,true);
            if(str.equals("")) return defaultValue;
            try
            {
                n=Integer.parseInt(str);
                break;
            }
            catch (NumberFormatException e)
            {
                System.out.println("数字输入错误,请重新输入:");
            }
        }
        return n;
    }
    /**
    从键盘读取一个长度不超过limit的字符串,并将其作为方法的返回值
     */
    public static String readString(int limit)
    {
        return readKeyBoard(limit,false);
    }
    /**
     从键盘读取一个长度不超过limit的字符串,并将其作为方法的返回值.
     若用户不输入字符而直接回车,方法将以defaultValue作为返回值。
     */
    public static String readString(int limit,String defaultValue)
    {
        String str=readKeyBoard(limit,true);
        return str.equals("")? defaultValue : str;
    }
    /**
     用于确认选择的输入。该方法从键盘读取‘Y’或’N’,并将其作为方法的返回值。
     */
    public static char readComfirmSelection()
    {
        char c;
        for(;;)
        {
            String str=readKeyBoard(1,false).toUpperCase();
            c=str.charAt(0);
            if(c=='Y'||c=='N') break;
            else
                System.out.println("选择错误,请重新输入:");
        }
        return c;
    }
}

<2>Customer类

public class Customer
{
    private String name;//客户姓名
    private char gender;//性别
    private int age;//年龄
    private String phone;//电话号码
    private String email;//电子邮箱
    public Customer()//构造器(空参)
    {}
    public Customer(String name,char gender,int age,String phone,String email)//构造器(全参)
    {
        this.name=name;
        this.gender=gender;
        this.age=age;
        this.phone=phone;
        this.email=email;
    }
    public void setName(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
    public void setGender(char gender)
    {
        this.gender=gender;
    }
    public char getGender()
    {
        return gender;
    }
    public void setAge(int age)
    {
        this.age=age;
    }
    public int getAge()
    {
        return age;
    }
    public void setPhone(String phone)
    {
        this.phone=phone;
    }
    public String getPhone()
    {
        return phone;
    }
    public void setEmail(String email)
    {
        this.email=email;
    }
    public String getEmail()
    {
        return email;
    }
    public void show()
    {
        System.out.println(name+gender+age+phone+email);
    }

<3>CustomerList类


public class CustomerList
{
    private Customer[] customers;  
    private int total = 0;  //total为数组的实际存储customer个数

    public CustomerList()//空参构造器
    {}

    /**
     * 构造器,来初始化数组,并指定数组的长度
     */
    public CustomerList(int totalCustomer)
    {
//        total=totalCustomer;我之前想的是total来记录数组的长度,他这里好像是用来记录数组存的customer元素的个数,所以这一行不应该出现
        customers = new Customer[totalCustomer]; //再次强调,数组的初始化只能在1)类的属性声明时和2)构造器中开展。
    }

    /**
     * 将形参customer添加到数组最后一个用户之后,若成功,返回true;若数组已满,返回false
     */
//    public boolean addCustomer(Customer customer)
//    {
//        int i=0;
//        while(true)//得到一个i值,这个i值表示数组元素的个数,及最后一个元素的下标-1
//        {
//            if(customers[i]!=null)
//            {
//                i++;
//                if(i==total)
//                {
//                    System.out.println("内存已满,你不可继续存储用户信息");
//                    return false;
//                }
//            }
//            else
//                break;
//        }
//        customers[i]=customer;//若数组未满,插入该customer
//        return true;
//    }
    public boolean addCustomer(Customer customer)
    {
        if (total >= customers.length)//如果数组中元素个数等于数组长度,则无法添加元素
            return false;
        else
        {
            customers[total] = customer;
            total++;
            return true;
        }
    }


    /**
     * 用参数customer替换数组中由index指定的对象,替换成功返回true;若index无效,则返回失败
     */
//    public boolean replaceCustomer(int index,Customer customer)
//    {
//        int i=0;
//        for(;;)//得到数组中现存有的元素的个数,应该为i+1个,i为最后一个元素的下标
//        {
//            if(customers[i]!=null)
//            {
//                i++;
//                if(i==total)
//                {
//                    break;
//                }
//            }
//            else
//                break;
//        }
//        if(index>=0&&index<=i)
//        {
//            customers[index]=customer;
//            return true;
//        }
//        else
//            return false;
//    }
    public boolean replaceCustomer(int index, Customer customer)
    {
        if (index >= 0 && index < total)
        {
            customers[index] = customer;
            return true;
        } else
            return false;
    }


    /**
     * 从数组中删除index指定索引位置的客户对象记录,删除成功返回true;删除失败,即索引无效,返回false
     */
//    public boolean deleteCustomer(int index)
//    {
//        int i=0;
//        for(;;)//得到数组中现存有的元素的个数,应该为i个,i-1为最后一个元素的下标
//        {
//            if(customers[i]!=null)
//            {
//                i++;
//                if(i==total)
//                {
//                    break;
//                }
//            }
//            else
//                break;
//        }
//        if(index>=0&&index<=i-1)
//        {
//        while(index>=0&&index<=i-1)//当index满足要求,若index为最后一个元素,该位置元素置空;若不是,该index后面的每一个customer往前进一位
//        {
//            if(index==i)
//                customers[index]=new Customer();
//            else
//            {
//                customers[index] = customers[index + 1];
//                index++;
//            }
//        }
//        return true;
//        }
//        else
//            return false;
//    }
    public boolean deleteCustomer(int index)
    {
        if (index >= 0 && index < total)
        {
            while (index < total - 1)//当index对应位置的元素不是数组中实际储存的最后一个元素时,后面的元素依次赋给前一个位置
            {
                customers[index] = customers[index+1];
                index++;
            }
            customers[total - 1] = null;//数组最后一个元素置空,不管是情况一:元素往前赋值后,留下的最后位置置为空;还是情况二:要删除的index刚好就是最后一个元素
            total--; //删了一个customer元素,total当然要减去1
            return true;
        } else
            return false;
    }


    /**
     * 返回数组中记录的所有customer对象,且返回的数组的长度与原customers数组中真实存储的元素个数相等
     */
//    public Customer[] getAllCustomers()
//    {
//        int i=0;
//        for(;;)//得到数组中现存有的元素的个数,应该为i+1个,i为最后一个元素的下标
//        {
//            if(customers[i].getName()!=null)
//            {
//                i++;
//                if(i==total)
//                {
//                    break;
//                }
//            }
//            else
//                break;
//        }
//        Customer[] custs=new Customer[i+1];
//        for(int j=0;j<=i;j++)
//            custs[j]=customers[j];
//        return custs;
//    }
    public Customer[] getAllCustomers()
    {
        Customer[] custs = new Customer[total];
        for (int i = 0; i < total; i++)
            custs[i] = customers[i];
        return custs;
    }


    /**
     * 返回index指定索引位置的customer记录
     */
//    public Customer getCustomer(int index)
//    {
//        int i=0;
//        for(;;)//得到数组中现存有的元素的个数,应该为i+1个,i为最后一个元素的下标
//        {
//            if(customers[i]!=null)//这里我之前写的是if(customers[i].getName()!=null),显示空指针错误,因为当customers[i]都为空时,它肯定不能再调方法了呀
//            {
//                i++;
//                if(i==total)
//                {
//                    break;
//                }
//            }
//            else
//                break;
//        }
//        if(index>=0&&index<=i)
//            return customers[index];
//        else
//        {
//            //System.out.println("错误,当前位置无元素");
//            return null;
//        }
//    }
    public Customer getCustomer(int index)
    {
        if(index>=0&&index<total)
            return customers[index];
        else
            return null;
    }

    /**
    获取数组中实际存储的customer元素的数量
    * */
    public int getTotal()
    {
        return total;
    }

    //******************************************************
    //测试用例
//    public static void main(String[] args)
//    {
//        CustomerList custs1=new CustomerList(5);
//
//        Customer a=new Customer();
//        a.setAge(12);
//        a.setEmail("914000@qq.com");
//        a.setGender('m');
//        a.setName("xxx");
//        a.setPhone("123456");
//
//       // custs1.addCustomer(a);
//        System.out.println(custs1.addCustomer(a));
//        custs1.replaceCustomer(3,a);
//        System.out.println(custs1.replaceCustomer(3,a));
//        for(int i=0;i<5;i++)
//        {
//            if(custs1.getCustomer(i)!=null)
//            {
//                custs1.getCustomer(i).show();
//            }
//        }
//        System.out.println(custs1.deleteCustomer(0));
//    }
}

<4>CustomerView类


public class CustomerView
{
    private CustomerList customerList = new CustomerList(10);
    /**
     * 添加客户的信息
     */
    private void addNewCustomer()
    {
        System.out.println("----------------------添加客户---------------------------");
        System.out.print("姓名");
        String name=CMUtility.readString(10);
        System.out.print("性别");
        char gender=CMUtility.readChar();
        System.out.print("年龄");
        int age=CMUtility.readInt();
        System.out.print("电话号码");
        String phone=CMUtility.readString(11);
        System.out.print("电子邮箱");
        String email=CMUtility.readString(20);
        Customer cust=new Customer();
        cust.setName(name);
        cust.setGender(gender);
        cust.setAge(age);
        cust.setPhone(phone);
        cust.setEmail(email);
        boolean isAdd=customerList.addCustomer(cust);
        if(isAdd==true)
            System.out.println("添加成功");
        else
            System.out.println("添加失败");
    }
    /**
     修改客户信息
     */
    private void modifyCustomer()
    {
        System.out.println("----------------------修改客户---------------------------");
        for(;;)
        {
            System.out.println("请输入编号,或按-1退出修改");
            int num = CMUtility.readInt(); //用户想修改的是第num个customer的信息,毕竟他不懂数组这些
            if (num == -1)
                return;
            if (num != -1 && num <= 0 && num > customerList.getTotal())
            {
                System.out.println("错误,没有该编号所对应的用户,请重新输入: ");
                continue;
            }
            else
            {
                Customer cust = customerList.getCustomer(num - 1); //这里的num应该减去一
                System.out.println("姓名:" + cust.getName() + ",如不需修改直接按回车键即可");
                cust.setName(CMUtility.readString(10, cust.getName()));
                System.out.println("性别" + cust.getGender() + ",如不需修改直接按回车键即可");
                cust.setGender(CMUtility.readChar(cust.getGender()));
                System.out.println("年龄" + cust.getAge() + ",如不需修改直接按回车键即可");
                cust.setAge(CMUtility.readInt(cust.getAge()));
                System.out.println("电话号码" + cust.getPhone() + ",如不需修改直接按回车键即可");
                cust.setPhone(CMUtility.readString(11, cust.getPhone()));
                System.out.println("电子邮箱" + cust.getEmail() + ",如不需修改直接按回车键即可");
                cust.setEmail(CMUtility.readString(15, cust.getEmail()));
            }
            System.out.println("是否要继续修改?请输入y or n");
            if(CMUtility.readComfirmSelection()=='N')
                return;
        }
    }
    /**
     删除客户信息
     * */
    private void deleteCustomer()
    {
        System.out.println("----------------------删除客户---------------------------");
        for (;;)
        {
            System.out.println("请输入待删除客户编号,或按-1退出删除");
            int num = CMUtility.readInt();
            if (num == -1)
                return;
            if (num != -1 && num <= 0 && num > customerList.getTotal())
            {
                System.out.println("错误,没有该编号所对应的用户,请重新输入: ");
                break;
            }
            else
            {
                System.out.println("是否确认删除?输入y or n");
                if (CMUtility.readComfirmSelection() == 'N')
                    return;
                else
                    customerList.deleteCustomer(num - 1);
            }
            System.out.println("是否继续删除其他客户");
            if(CMUtility.readComfirmSelection()=='N')
                return;
        }
    }
    /**
     输出所有客户的信息
     * */
    private void listAllCustomers()
    {
        System.out.println("----------------------客户列表---------------------------");
        int total=customerList.getTotal();
        if(total==0)
        {
            System.out.println("当前没有存储没有客户数据");
        }
        else
        {
            System.out.println("编号\t姓名\t\t性别\t年龄\t电话\t\t邮箱");
            Customer[] custs=customerList.getAllCustomers();
            for(int i=0;i<custs.length;i++)
            {
                System.out.println((i+1)+"\t\t"+custs[i].getName()+"\t\t"+custs[i].getGender()+"\t\t"+custs[i].getAge()+"\t"+custs[i].getPhone()+"\t"+custs[i].getEmail());
            }
        }
        System.out.println("--------------------------------------------------------");
    }
    /**
     主菜单,调用前面的私有方法
     **/
    public void enterMainMenu()
    {
//CustomerView cuew=new CustomerView();
// 在类中调用本类中的方法,不用再去声明一个对象,然后通过对象调方法,可以直接使用方法
// 比如,不用写  CustomerView cuew=new CustomerView();  cuew.addNewCustomer();
// 可以直接写成addNewCustomer();
        boolean isTrue=true;
        while (isTrue)
        {
            System.out.println("*******客户信息管理软件*********");
            System.out.println("         1.添加客户         ");
            System.out.println("         2.修改客户         ");
            System.out.println("         3.删除客户         ");
            System.out.println("         4.客户列表         ");
            System.out.println("         5.退出程序         ");
            System.out.println("         请选择1-5:_        ");
            char c = CMUtility.readMenuSelection();
            //CMUtility cmu = new CMUtility();
            //想用其他类中的方法,当其他类中的方法是static时,不用总是先声明一个对象,然后通过对象调用方法
            //CMUtility类中,其readMenuSelection是static的,所以:
            //比如,不用写  CMUtility cmu = new CMUtility(); char c=cmu.readMenuSelection();
            //可以直接写成char c=CMUtility.readMenuSelection();
            switch (c)
            {
                case '1':
                    addNewCustomer();
                    break;
                case '2':
                    modifyCustomer();
                    break;
                case '3':
                    deleteCustomer();
                    break;
                case '4':
                    listAllCustomers();
                    break;
                case '5':
                    System.out.println("确定是否退出?");
                    if(CMUtility.readComfirmSelection()=='Y')
                        isTrue=false;
                    break;
            }
        }
    }

    public static void main(String[] args)
    {
        CustomerView a=new CustomerView();
        a.enterMainMenu();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值