《Java基础入门 极速版》

ch04 面向对象


4.0 导引

面向过程编程(如C语言) 程序 <==>过程顺序

步骤:顺序执行、分支执行、循环执行、子程序定义和调用

思考问题的方式

事情、物体 ==> 事物、对象、Object,以事物为核心的思考方式

面向对象的程序设计思想(如Java语言) 程序 = Σ静态属性+动态方法

特征、特性、属性:静态

行为、过程、方法:动态

面向对象的程序设计思想主要概念

类和对象、封装、继承、多态、抽象类、接口

4.1 类和对象

4.1.1 基本概念

(1) 面向对象

①Java语言是一种面向对象的语言。

面向对象的思想是把问题看成是由若干个对象组成,这些对象之间是独立的,但又可以相互配合、连接和协调,从而共同完成整个程序要实现的任务和功能。

③面向对象的三大特征:封装、继承和多态。

(2) 对象解释

①对象是用来描述客观事物的一个实体。

②用面向对象方法解决问题时,要对现实世界中的对象进行分析和归纳,找出哪些对象与要解决的问题是相关的。

③万事万物皆对象

(3) 类解释

(4) 类和对象的关系

类和对象的关系就是抽象和具体的关系:

4.1.2 定义类、实例化对象

(1) 面向对象设计的过程

面向对象设计的过程就是抽象的过程,一般分为3步来完成:

(2) 定义类、创建对象的语法格式

[访问修饰符] class 类名{
    //属性类型  属性名称  = 属性值;
    //void 方法名(参数){ 功能代码 }
}
// 访问修饰符有:public、private、protected、缺省4种。


// TODO 1. 先声明类
// TODO 2. 声明属性,所谓的属性其实就是类中的变量
//         变量类型  变量名称  = 变量值
//         [访问修饰符] 属性类型  属性名称  [= 属性值];
// TODO 3. 声明方法
//          [访问修饰符] 返回类型 方法名(参数类型 参数名1 [,...]){ 功能代码 }
// TODO 4. 创建对象
//         类名 对象名 = new 类名();
// TODO 5. 执行方法
//         对象.属性
//         对象.方法名()
//         访问修饰符有:public、private、protected、缺省4种。
//         返回类型: void -- 无返回数据类型,不需要return语句;其他数据类型,需要return语句

(3) 方法分类

【例题1】面向对象举例1

package cn.du.ch04;

public class Java02_Object_1 {
    public static void main(String[] args) {

        // TODO 面向对象
        //所谓的面向对象,其实就是分析问题时,以问题所涉及到的事或物为中心的分析方式
        // 类和对象
        // 类表示归纳和整理(抽象)
        // 对象就表示具体的事物(具象)
        // TODO class(类)
        /*
          类的语法基本语法结构:

          class 类名 {
             特征(属性),
             功能(方法)
          }

          创建对象的语法:
          new 类名();
         */

        // 问题:做一道菜,红烧排骨
        // 类:菜, 对象:红烧排骨



        System.out.println("面向对象的程序设计思想【杜老师编制】");
        // 引用数据类型
        Cooking c = new Cooking();
        c.name = "红烧排骨";
        c.food = "排骨";
        c.execute();

        Cooking c1 = new Cooking();
        c1.name = "红烧鱼";
        c1.food = "鲫鱼";
        c1.execute();

    }
}
class Cooking {

    // 特征(属性)
    // 名字
    String name;
    // 菜的类型
    String type = "红烧";
    // 食材
    String food;
    // 佐料
    String relish = "大料";

    // TODO 执行
    void execute() {
        System.out.println("准备食材:" + food);
        System.out.println("准备佐料:" + relish);
        System.out.println("开始烹饪");
        System.out.println(name + "烹饪完成\n");
    }
}
图1 面向对象举例

【例题2】面向对象举例2

package cn.du.ch04;

public class Java01_Object_2 {
    public static void main(String[] args) {
        // TODO 面向对象
        // 类:动物
        // 对象:猫,狗
        Animal a1 = new Animal();
        a1.type = "猫";
        a1.name = "小黑";
        a1.run();

        Animal a2 = new Animal();
        a2.type = "狗";
        a2.name = "大黄";
        a2.run();
    }
}
class Animal {
    String type;
    String name;

    void run() {
        System.out.println(type + " " + name + "跑开了【杜老师编制】");
    }
}
图2 面向对象举例2

【例题3】面向对象举例3

package cn.du.ch04;

public class Java01_Object_3 {
    public static void main(String[] args) {

        // TODO 面向对象
        // 狗 : 2只,小黑,小白
        Dog dog1 = new Dog();
        dog1.color = "white";
        dog1.name = "小白";
        dog1.run();

        Dog dog2 = new Dog();
        dog2.color = "black";
        dog2.name = "小黑";
        dog2.run();
    }
}
class Dog {
    String color;
    String name;

    void run() {
        System.out.println(name + "跑开了【杜老师编制】");
    }
}
图3 面向对象举例3

【例题4】面向对象举例4

package cn.du.ch04;

public class Java01_Object_4 {
    public static void main(String[] args) {

        Teacher t = new Teacher();
        t.name = "杜兆将";
        t.teach();

        Student s = new Student();
        s.name = "赵晋民";
        s.study();
    }
}
class Teacher {
    String name;
    void teach() {
        System.out.println(name + "老师,在讲课【杜老师编制】\n");
    }
}
class Student {
    String name;
    void study() {
        System.out.println("学生" + name + ",在听课【杜老师编制】\n");
    }
}
图4 面向对象举例4

【知识的】面向对象的基本语法

package cn.du.ch04;

public class Java02_Object {
    public static void main(String[] args) {
        // TODO 面向对象 基本语法
        /*
          基本语法:
              声明
                   class 类名  {
                        // 属性 (0个或多个)
                        类型 名称 = 值
                        // 方法(行为,0个或多个)
                        void 方法名() {
                            逻辑代码
                        }
                   }
              使用
                   构建对象: new 类名()
                   访问属性:对象.属性名
                   访问方法:对象.方法名()
         */
    }
}

【例题5】类的实例化

package cn.du.ch04;

public class Java04_Object_Class {
    public static void main(String[] args) {

        // TODO 面向对象
        // 类:结构体,里面包含了属性(特征)和方法(行为)
        //    会有很多的对象。
        // class : 关键字(全是小写)
        // 类名:类的名称,标识符。遵循规则。一般情况下,类名的首写字母是大写【规范】。但首字母小写或采用汉字也可。

        // 对象:类的实例化(具象化)
        //      new 类名(),下括号需要增加。
        //      new也是关键字,表示创建一个具体的对象,而且,使用一次,创建一次,每次都是全新的对象。
        // 一般new出来的对象会赋值给变量,方便重复使用
        // 变量的类型就是对象的类型。
        // 对象是将内存地址赋值给了变量,所以变量其实引用了内存中的对象,所以称之为引用变量,
        // 而变量的类型称之为引用数据类型。

        System.out.println("类的实例化【杜老师整理】");
        User04 user1 = new User04();
        User04 user2 = new User04();
        User04 user3 = new User04();
        User04 user4 = new User04();
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user3);
        System.out.println(user4);

        // 特殊的对象:空对象(null),没有引用的对象,称之为空对象, 关键字对象。
        // 所有引用类型变量的默认取值就是null
        User04 user5 = null;
        System.out.println(user5);
    }
}
class User04 {

}
图5 对象:类的实例化(具象化)

【例题6】面向对象-属性

package cn.du.ch04;

public class Java05_Object_Field {
    public static void main(String[] args) {

        // TODO 面向对象 - 属性
        // 所谓的属性,其实就是类的对象的相同特征。
        // 语法和变量的声明很像。
        // 属性类型 属性名称 = 属性值
        // 如果在声明属性的同时进行了初始化赋值,那么所有对象的属性就完全相同
        // 所以如果希望每个对象的属性不一致,那么可以不用在声明属性的时候进行初始化。
        // 那么属性会在构造对象的时候默认初始化,而默认初始化的值取决鱼属性的类型.
        // byte ,short, int ,long => 0
        // float, double => 0.0
        // boolean flg = false
        // char = 空字符
        // 引用数据类型 => null

        // 变量的作用域非常小,只在当前的大括号内有效
        // 属性不仅仅在当前类中有效,而且可以随着对象在其他地方使用
        // 变量使用前必须初始化,否则会出现错误,属性可以不用初始化,因为JVM会帮助我们自动完成初始化。
        System.out.println("面向对象-属性【杜老师改编】");
        int i;
        String str;
        String name = "杜老师";
        //System.out.println("int i = "+i);  //变量 'i' 可能尚未初始化 爆红
        //System.out.println("String str = "+str); //变量 'str' 可能尚未初始化 爆红
        System.out.println("String name = "+name);
        User05 user = new User05();
        System.out.println("user.姓名 = "+user.姓名);
        user.姓名 = "杜兆将";
        System.out.println("user.姓名 = "+user.姓名);
    }
}
class User05 {
    String 姓名;
}
图6 面向对象-属性

【例题7】面向对象-方法

package cn.du.ch04;

public class Java06_Object_Method {
    public static void main(String[] args) {

        // TODO 面向对象 - 方法
        // 类的行为称之为方法。
        // TODO 基本的语法为:void 方法名(){ 方法的逻辑代码 }
        // 既然方法是对象的行为,那么行为就会有结果,而结果可能会对其他对象有影响
        // TODO 扩展语法: 返回值类型[void] 方法名(){ 方法的逻辑代码 }
        //  方法就是行为,所以会有结果,如果想要结果给其他人使用,那么需要在方法中返回这个结果。
        //       void关键字表示无需返回,也就是方法的结果没有人使用。
        //  如果想要结果给其他人使用,那么需要在方法中返回结果,并将void改成返回值的类型。
        //  方法的结果需要采用return关键字进行返回。
        System.out.println("面向对象-方法【杜老师编制】");
        User06 user = new User06();
        boolean registerResult = user.register();
        if ( registerResult ) {
            System.out.println("注册成功,请登录");
            boolean loginResult = user.login();
            if (loginResult) {
                System.out.println("登录成功");
            } else {
                System.out.println("登录失败");
            }
        } else {
            System.out.println("注册不成功,请重新注册");
        }
    }
}

class User06 {
    boolean register() {
        System.out.println("注册软件系统");
        // 成功 true
        return false;
        // 失败 false
    }
    boolean login() {
        System.out.println("登录软件系统");
        return true;
    }
}
图7 面向对象-方法

【例题8】面向对象-方法-参数、可变参数

package cn.du.ch04;

public class Java07_Object_Method_Param {
    public static void main(String[] args) {
        // TODO 面向对象 - 方法 - 参数、可变参数
        // 从外部获取数据控制方法的内容逻辑实现的语法操作,我们称之为参数。也叫方法参数。
        // 方法的参数语法类似于变量:类型 名称,但是需要在方法后面的小括号中使用
        // 参数可以有多个,如果有多个,那么使用逗号隔开。
        // 如果方法声明了参数,那么调用时必须传递参数,否则发生错误。
        // TODO 扩展语法: 返回值类型[void] 方法名(参数类型 参数名)

        // 如果参数有多个的话,那么在传值的时候需要注意:
        // 1. 个数不能缺失
        // 2. 类型必须匹配
        // 3. 顺序必须匹配
        // 将方法后面的小括号中的所有参数称之为参数列表

        // 如果参数的类型(含义)相同,但是个数不确定的场合,JVM提供了可变参数 : 参数的长度可变
        // 参数类型...参数名
        // 传值的个数也可以是变化的。
        System.out.println("面向对象-方法-参数、可变参数【杜老师改编】");
        User07 user = new User07();
        user.sayHello("杜老师", 60);
        //user.sayHello(40, "李四"); // 参数类型不匹配 爆红

        user.printUser(30);
        user.printUser(40, "张三");
        user.printUser(50, "张山", "李思", "王武");

        // 如果参数列表中含有不同含义的多个参数,那么可变参数必须放置在最后,否则出现错误
    }
}
class User07 {
    void sayHello( String 姓名, int 年龄 ) {
        System.out.println("Hello "+姓名+", 今年你"+年龄);
    }
    void printUser( int age, String... name  ) {
        System.out.print("你们好!你们的年龄是"+age+"岁,名字分别是:");
        for (String x:name)
            System.out.print(x+"\t");
        System.out.println();
    }
}
图8 面向对象-方法-参数、可变参数

【例题9】面向对象-方法-参数: 方法参数的传递为值传递

package cn.du.ch04;

public class Java07_Object_Method_Param_1 {
    public static void main(String[] args) {
        // TODO 面向对象 - 方法 - 参数
        // Java种方法参数的传递为值传递
        // 基本数据类型:数值
        // 引用数据类型:引用地址
        System.out.println("面向对象-方法-参数: 方法参数的传递为值传递【杜老师编写】");
        int i = 10;
        System.out.println("test(i)之前,i="+i);// 10
        test(i);
        System.out.println("test(i)之后,i="+i);// abc10

        String s = "abc";
        System.out.println("\ntest(s)之前,s="+s);// abc
        test(s);
        System.out.println("test(s)之后,s="+s);// abc10


        User user = new User();
        user.name = "杜老师";
        System.out.println("\ntest(user)之前,user.name="+user.name);
        test(user);
        System.out.println("test(user)之后,user.name="+user.name);

    }
    public static void test(int i) {
        i = i + 10;
    }
    public static void test(String s) {
        s = s + 10;
        // 将产生一个新的字符串变量地址
    }
    public static void test(User user) {
        user.name = "李思";
    }
}
class User {
    String name;
}
图9 面向对象-方法-参数: 方法参数的传递为值传递
图10 方法压栈弹栈、基本数据类型参数传递为值传递
图11 引用数据类型方法参数的传递为地址传递

4.2 封装

封装(Encapsulation)是面向对象方法]重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。

封装 ,大白话的解释就是,把一个东西,装到箱子了,只留小小的口,用于外界访问。

在java中通过关键字private,protected和public实现封装。什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。

通常,应禁止直接访问一个对象中数据的实际表示,而是应该通过操作接口来访问,这叫信息隐藏。通过属性私有和public getter/setter访问。

封装概述

https://hh419.blog.csdn.net/category_11980901_2.html

01、JDK安装及Java开发环境变量配置
02、MyEclipse常用操作和常用快捷键
03、MyEclipse项目创建步骤(小白详解)
04、进制(二进制、八进制、十进制、十六进制)
05、JAVA入门——变量和数据类型
06、JAVA入门——常用运算符和运算符的优先级
07、JAVA入门——if选择结构
08、JAVA入门——switch选择结构
09、JAVA入门——循环结构
10、JAVA入门——多重循环及程序调试
11、JAVA入门——一维数组
12、JAVA入门——二维数组

13、JAVA入门——对象和类
14、JAVA入门——方法和构造方法
15、JAVA入门——封装
16、JAVA入门——继承和方法重写
17、JAVA入门——多态、抽象方法和抽象类
18、JAVA入门——接口

19、JAVA入门——异常

20、JAVA进阶——集合(1)
21、JAVA进阶——集合(2)
22、JAVA进阶——实体类应用
23、JAVA进阶——日期操作类
24、JAVA进阶——File类
25、JAVA进阶——输入输出流
26、JAVA进阶——多线程
27、JAVA进阶——线程同步和线程间的通信
28、JAVA进阶——网络和IP地址
29、JAVA进阶——端口、域名、DNS、网络服务器、协议
30、JAVA进阶——Socket编程
31、JAVA进阶——XML知识
32、JAVA进阶——解析XML技术

15 JAVA入门——封装
一、封装
1、封装概述
2、封装的步骤
二、Java里的包
1、包的概述
2、包的定义
3、包的使用
4、注意事项
三、Java访问修饰符
1、类和类成员的访问控制
2、类的访问修饰符
3、类成员的访问修饰符
四、static关键字
1、static特点
2、static修饰属性
3、static修饰方法
4、static修饰代码块

4. static关键字

特点、修饰属性、修饰方法、修饰代码块

【例题10】静态(类变量)

package cn.du.ch04;

public class Java08_Object_Static {
    public static void main(String[] args) {

        // TODO 面向对象
        // 针对于具体对象的属性称之为对象属性,成员属性,成员变量,实例属性
        // 针对于具体对象的方法称之为对象方法,成员方法,成员函数,实例方法
        // 把和对象无关,只和类相关的称之为静态,
        // 和类相关的属性称之为静态属性,可以理解为类中所有对象都具有的共同且相同的属性
        // 和类相关的方法称之为静态方法,可以理解为类中所有对象都具有的共同且相同的方法
        // 静态语法就是在属性和方法前增加static关键字
        System.out.println("面向对象:成员属性和成员方法、静态属性和静态方法【杜老师整理】");
        Chinese c = new Chinese();
        Chinese c1 = null;
        c.姓名 = "杜老师";

        System.out.println("Hello " + c.姓名 + ", " + c.国籍);
        // System.out.println("Hello " + c1.姓名 + ", " + c1.国籍); //产生运行时的NullPointer异常
        System.out.println("Chinese.国籍= " + Chinese.国籍);
        Chinese.国籍="美国";
        System.out.println("Chinese.国籍= " + Chinese.国籍);

        Bird.fly();
        System.out.println(Bird.type);
    }
}
class Bird {
    static String type = "鸟";
    static void fly() {
        System.out.println("鸟在飞翔...");
    }
}
class Chinese {
    String 姓名;
    static String 国籍 = "中国";
}
图12 静态变量(类变量)

JVM内存的划分有五片:

图13 Java变量分类

变量类型 存放位置
局部变量 栈区
成员变量
静态变量 方法区(静态区)
全局变量 方法区
全局常量 全局数据区
图14 Java变量存储

【例题11】静态方法(类方法)

package cn.du.ch04;

public class Java08_Object_Static_1 {
    public static void main(String[] args) {

        // TODO 面向对象 - 静态

        // TODO 先有类,再有对象。
        // 成员方法可以访问静态属性和静态方法
        // 静态方法不可以访问成员属性和成员方法
        Test t = new Test();
        t.name = "杜老师";
        t.type = "教师";
        t.test();
        t.test1();
        Test.test1();
    }
}
class Test {
    String name;  // 成员属性
    static String type;  //类属性 -- 静态属性

    void test() {
        test1();
        System.out.println(type+": "+ name);
        System.out.println("成员方法test...");
    }
    static void test1() {
        // test();  // 静态方法不可以访问成员方法 爆红
        // System.out.println(name);  // 静态方法不可以访问成员属性和成员方法 爆红
        System.out.println("类方法test1...");
    }
}
图15 静态变量和静态方法

【例题12】静态代码块

package cn.du.ch04;

public class Java08_Object_Static_2 {
    public static void main(String[] args) {

        // TODO 面向对象 - 静态

        // 类的信息加载完成后,会自动调用静态代码块,可以完成静态属性的初始化功能
        // 对象准备创建时,也会自动调用代码块,但不是静态的
        System.out.println("面向对象-静态代码块【杜老师改编】");
        System.out.println("----静态方法User08.test()执行显示:");
        User08.test();
        System.out.println("\n----new User08()执行显示:");
        new User08();
    }
}
class User08 {
    static {
        // 静态代码块
        System.out.println("静态代码块执行1");
    }
    static {
        // 静态代码块
        System.out.println("静态代码块执行2");
    }
    static void test() {
        System.out.println("静态方法测试test...");
    }
    {
        System.out.println("  代码块执行1");
    }
    static {
        // 静态代码块
        System.out.println("静态代码块执行3");
    }
    {
        System.out.println("  代码块执行2");
    }
}
图16 静态方法
图17 静态代码块

2. 包:包的概述、定义、使用、注意事项

【例题13】包package

package cn.du.ch04;

public class Java09_Object_Package {
    public static void main(String[] args) {

        // TODO 面向对象 - package - 包 - 源代码的存放路径(文件目录)
        // package中容纳类
        // 基本语法: package 包完整路径;
        // 路径中的多个包使用点隔开
        // java.lang.Object
        // 主要功能用于分类管理

        // 一个类可以没有包,但是package不可以在同一个源码文件中使用多次
        // 包名为了区分类名,所以一般全部都是小写。
        // java.lang.Object

        // Java中存在不同包的相同名称的类,可以使用包进行区分
        // 一般情况下,在使用类的情况下,我们都会使用类的全名(包名+ 类型)
        new java.util.Date();
    }
}

【例题14】import导入包

package cn.du.ch04;
import java.util.*;
import cn.du.ch04.*; //当前包 cn.du.ch04 可省路 import
public class Java10_Object_Import {
    public static void main(String[] args) {

        // TODO 面向对象 - import
        // import 主要用于在使用类前准备好了。
        // import语句只能使用在package后,class前。
        // import关键字可以多次使用,导入多个类
        // 如果同一个包中需要导入大量的类,那么可以使用通配符星号来简化操作。
        // 如果import了不同保重相同名称的类,那么还是需要在使用时增加包名。
        // 全类名=包名+类名: cn.du.ch04.Java10_Object_Import

        System.out.println("面向对象-import【杜老师整理】");
        java.lang.String unit = "山西传媒学院";
        String name = "杜老师";
        // import java.lang.*; 可省路
        java.util.Date d = new java.util.Date();
        System.out.println(d);
        new ArrayList();

        new cn.du.ch04.Java10_Object_Import();
        new Java10_Object_Import();
        new User10();
        // 当前包 cn.du.ch04 同包 可省路 import
    }
}
class User10 {

}
图18 Import导入包

3. 访问修饰符

【例题28】面向对象 - 访问权限

package cn.du.ch04;
public class Java17_Object_Access {
    public static void main(String[] args) {
        //TODO 面向对象 - 访问权限
        // public : 公共的,访问权限修饰符
        //         Java的源码中,公共类只能有一个,而且必须和源码文件名相同
        //         main方法:main方法是由JVM调用的,JVM调用时应该可以任意调用,而不用考虑权限问题。

        //TODO Java中的访问权限主要分为4种:
        //   1. private : 私有的, 同一个类中可以使用
        //   2. (default) : 默认权限, 当不设定任何权限时,JVM会默认提供权限,包(路径)权限
        //   3. protected : 受保护的权限, 子类可以访问
        //   4. public : 公共的, 任意使用

        User17 user = new User17();
        user.username = "Dzjiang";
        user.sex = "男";
        user.age = 60;
        // System.out.println(user.name);  //私有属性name 爆红
        System.out.println("public属性 "+user.username);
        System.out.println("默认   属性 "+user.sex);
        System.out.println("protected属性 "+user.age);
    }
}

class User17 {
    private String name;
    public String username;
    String sex;

    protected int age;

    void test() {
        System.out.println(age);
        System.out.println(name);
        System.out.println(username);
    }
}

class Child17 extends User17 {
    void test() {
        System.out.println(age);
    }
}
图33 访问修饰符

【例题29】Java类的公共始祖:java.lang.Object

package cn.du.ch04;
public class Java17_Object_Access_1 {
    public static void main(String[] args) {

        // TODO 面向对象 - 访问权限
        Person17 person = new Person17();

        // private : 同类
        // default : 同类,同包(路径)
        // protected:同类,同包(路径),子类
        // public :公共的
        // 所谓的访问权限,其实就是访问属性,方法的权力和限制。
        // 谁访问?Java17_Object_Access_1 -> super -> java.lang.Object
        // 访问谁的?Person17 -> super -> java.lang.Object(clone)
//        person.clone();
    }

}
class Person17 {

    void test() throws Exception {
        clone();
    }
}

【例题30】面向对象 - 外部类 - 内部类

package cn.du.ch04;

public class Java18_Object {
    public static void main(String[] args) {

        // TODO 面向对象 - 外部类 - 内部类
        // Java不允许外部类使用private, protected修饰
        // 外部类只能用public或缺省模式修饰
        // 所谓的外部类,就是在源码中直接声明的类
        // 所谓的内部类,就是类中声明的类

        // 内部类就当成外部类的属性使用即可

        // 因为内部类可以看作外部类的属性,所以需要构建外部类对象才可以使用
        System.out.println("面向对象-外部类-内部类【杜老师整理】");
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass innerClass = outer.new InnerClass();
        System.out.println(outer);
        System.out.println(innerClass);
    }
}
class OuterClass {
    public class InnerClass {

    }
}
图35 面向对象-外部类-内部类

【例题31】面向对象 - 单例模式

package cn.du.ch04;

public class Java19_Object {
    public static void main(String[] args) {

        // TODO 面向对象 - 单例模式
        // JVM默认给类提供的构造方法,其实就是公共的,无参的构造方法
        // 1. 类的创建过程复杂
        // 2. 类的对象消耗资源
        //User19 user = new User19();
        User19 instance1 = User19.getInstance();
        User19 instance2 = User19.getInstance();
        User19 instance3 = User19.getInstance();
        User19 instance4 = User19.getInstance();
        User19 instance5 = User19.getInstance();
        User19 instance6 = User19.getInstance();

        System.out.println(instance1.equals(instance6));
    }
}
class User19 {
    private static User19 user19 = null;

    private User19() {

    }
    public static User19 getInstance() {
        if ( user19 == null ) {
            user19 = new User19();
        }
        return user19;
    }
}
图36 面向对象-单例模式

1. Bean规范(封装的步骤)

【例题25】Bean规范(封装的步骤)

package cn.du.ch04;

public class Java25_Object {
    public static void main(String[] args) {

        // TODO 面向对象
        // 1. 主要用于编写逻辑
        // 2. 主要用于建立数据模型(Bean) 数据特征的抽象
        // TODO Bean类得设计规范:Bean规范
        // 1. 类要求必须含有无参,公共得构造方法
        // 2. 属性必须私有化,然后提供公共得,set,get方法

        System.out.println("数据模型(Bean规范)【杜老师改编】");
        User251 user1 = new User251();
        user1.account = "admin";
        user1.password = "123456";
        System.out.println("登录结果 = "+user1.login());

        User252 user2 = new User252();
        user2.account = "admin";
        user2.password = "12345";
        System.out.println("登录结果 = "+User252.login(user2.account,user2.password));

        User25 user = new User25();
        user.setAccount("admin");
        user.setPassword("123456") ;
        System.out.println("数据模型(Bean) 登录结果 = "+login(user));
    }
    public static boolean login( User25 user ) {
        if ( user.getAccount().equals("admin") && user.getPassword().equals("123456") ) {
            return true;
        } else {
            return false;
        }
    }
}

class User251 {
    String account;
    String password;
    boolean login(){  // login 登录方法 从业务逻辑上来说是类的方法,不是成员方法,此处不合适
        if ( account.equals("admin") && password.equals("123456") ) {
            return true;
        } else {
            return false;
        }
    };
}
class User252 {
    public String account;
    public String password;
    static boolean login(String account, String password){
        // login 登录方法 从业务逻辑上来说是类的方法,此处虽是类方法,但User252作为数据模型类中定义业务逻辑方法此处也不合适
        if ( account.equals("admin") && password.equals("123456") ) {
            return true;
        } else {
            return false;
        }
    };
}
class User25 {
    private String account;
    private String password;

    public void setAccount( String account ) {
        this.account = account;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAccount() {
        return account;
    }
    public String getPassword() {
        return password;
    }
}
图25 Bean规范(封装的步骤)

封装的作用

① 对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。

②对象的数据封装特性还可以把对象的私有数据和公共数据分离开,保护了私有数据,减少了可能的模块间干扰,达到降低程序复杂性、提高可控性的目的。

【例题15】面向对象-构建对象-构造方法

package cn.du.ch04;

public class Java11_Object_Instance {
    public static void main(String[] args) {

        // TODO 面向对象 - 构建对象 - 构造方法
        // 构造方法:专门用于构建对象 - 使用new 类名(参数)来构造
        // 如果一个类中没有任何的构造方法,那么JVM会自动添加一个公共的,无参的构造方法,方便对象的调用
        // TODO : 基本语法: 类名(){}
        //  1. 构造方法也是方法,但是没有void关键字。
        //  2. 方法名和类名完全相同
        //  3. 如果类中没有构造方法,那么JVM会提供默认的构造方法----无参构造方法
        //  4. 如果类中有构造方法,那么JVM不会提供默认的构造方法
        //  5. 构造方法也是方法,所以也可以传递参数,但是一般传递参数的目的是用于对象属性的赋值
        System.out.println("面向对象-构建对象-构造方法【杜老师整理】");
        System.out.println("实例化 new 之前 before...");
        User11 user = new User11("杜老师");
        System.out.println("实例化 new 之后 after...");
        user.test();
        System.out.println("user.username="+user.username);
        // 代码块,是在构造对象之前执行的
    }
}
class User11 {
    String username;

    {
        System.out.println("  代码块1");
    }

    User11(String name) {
        username = name;
        System.out.println("  构造方法 user...");
    }
    {
        System.out.println("  代码块2");
    }
    void test() {
        System.out.println("测试方法 test...");
    }
    {
        System.out.println("  代码块3");
    }
}
图19 面向对象-构建对象-构造方法

4.3 继承 extends扩展

【例题16】面向对象 - Extends - 继承

package cn.du.ch04;

public class Java12_Object_Extends {
    public static void main(String[] args) {

        // TODO 面向对象 - Extends - 继承
        // 面向对象变成中有3个非常重要的特征:继承,封装,多态
        // 类存在父子关系:子类可以直接获取到父类的成员属性和成员方法。
        // 类的继承只能是单继承,一个类只能有一个父类,不能存在多个父类
        // 一个父类可以有多个子类
        // 继承采用extends语法: 子类 extends 父类
        System.out.println("面向对象-Extends-继承【杜老师改编】");
        Child c = new Child();
        System.out.println("子类 extends 父类 属性 name="+c.name);
        System.out.print("子类 extends 父类 方法 test():");
        c.test();
    }
}
class Parent {
    String name = "杜老师";
    void test() {
        System.out.println("Parent 的 test() 方法");
    }
}
class Child extends Parent {

}
图20 面向对象-Extends-继承

【例题17】面向对象-Extends-继承: super & this

package cn.du.ch04;

public class Java12_Object_Extends_1 {
    public static void main(String[] args) {

        // TODO 面向对象 - Extends - 继承: super & this
        // 如果父类和子类含有相同的属性,那么可以采用特殊的关键字进行区分
        // super & this.
        System.out.println("面向对象-Extends-继承:super & this");
        Child0 c0 = new Child0();
        System.out.println(c0.name);
        Child1 c = new Child1();
        System.out.println(c.name);
        c.test();

    }
}
class Parent1 {
    String name = "杜老师";
}
class Child1 extends Parent1 {
    String name = "李四";
    void test() {
        System.out.println("super.name="+super.name);
        System.out.println("this.name="+this.name);
        System.out.println("name="+name);
    }
}
class Child0 extends Parent1 {

}
图21 面向对象-Extends-继承: super this

【例题18】面向对象-Extends-继承:super()

package cn.du.ch04;

public class Java12_Object_Extends_2 {
    public static void main(String[] args) {

        // TODO 面向对象 - Extends - 继承
        // 构造方法
        // 父类对象是在子类对象创建前创建完成,创建子类对象前,会调用父类的构造方法完成父类的创建
        // 默认情况下,子类对象构建时,会默认调用父类的构造方法完成父类对象的创建。使用的是super的方式,只不过JVM自动完成
        // 如果父类提供构造方法,那么JVM不会提供默认的构造方法,那么子类应该显示调用super方法构建父类对象。
        System.out.println("面向对象-Extends-继承:super()【杜老师改编】");
        Child2 c1 = new Child2();
        Child2 c2 = new Child2();
        Child2 c3 = new Child2();
        // 分别构造3个子类对象,不会构建3个父对象----只是调用了3次父对象的构造方法。

        Child3 cc1 = new Child3();
        Child3 cc2 = new Child3();
        Child3 cc3 = new Child3();
        System.out.println(cc3.username);

        // new : 一个new只会构建一个对象
    }
}
class Parent2 {

    Parent2 () {
        System.out.println("parent2...");
    }
}
class Child2 extends Parent2 {

    Child2() {
        System.out.println("child2...\n");
    }
}

class Parent3 {
    String username;

    Parent3 (String name) {
        username = name;
        System.out.println("Parent3的有参构造方法Parent3 (String name)运行。parent...");
    }
}
class Child3 extends Parent3 {

    Child3() {
        super("杜老师");
        System.out.println("Child3的无参构造方法运行。child...\n");
    }
}
图22 面向对象-Extends-继承:super()
图23 父子类定义和子类实例化

【例题24】子类方法重写

package cn.du.ch04;

public class Java15_Object {
    public static void main(String[] args) {
        // TODO 面向对象 - 重写
        /* 方法的重写:父类对象的方法其实主要体现通用性,无法在特殊的场合下使用
        //           如果子类对象需要在特殊的场合下使用,那么就需要重写方法的逻辑,这个操作在Java中称之为方法的重写
        // 这里的重写,并不仅意味着父类的方法被覆盖掉,只是在当前场合不使用。如果使用super关键字还是可以访问
        // 方法的重写要求,子类的方法和父类的方法,方法名相同,返回值类型相同,参数列表要相同*/
        System.out.println("面向对象-子类重写(覆盖)父类的属性或方法【杜老师】"); 
        Child15 child = new Child15();
        child.test();
    }
}
class Parent15 {
    String 姓名 = "张一";

    void test() {
        System.out.println("父类parent test...");
    }
}
class Child15 extends Parent15 {
    String 姓名 = "张小一";
    void test() {
        System.out.println("子类child test...");
        System.out.println("子类child中 this.姓名 = "+this.姓名);
        System.out.println("子类child中 super.姓名" + super.姓名);
        super.test();
    }
}
图30 子类重写

【例题26】子类重写练习

package cn.du.ch04;

public class Java15_Object_1 {
    public static void main(String[] args) {

        // TODO 面向对象 - 重写
        CCC ccc = new CCC();
        System.out.println("父类的方法 "+ccc.sum());

        DDD ddd = new DDD();
        System.out.println("子类的方法 "+ddd.sum());

        CCC eee = new DDD();
        System.out.println("new DDD()中存在sum方法,子类的方法 "+eee.sum());
        // 一个对象能使用什么方法,取决于引用变量的类型。  CCC eee
        // 一个对象的方法具体的使用(直接,间接)是需要看具体的对象的   = new DDD()

        CCC eeee = new DDDD();
        System.out.println("new DDDD()中没有sum方法,执行父类的方法 "+eeee.sum());

        // 一个对象能使用什么属性,取决于引用变量的类型
        // 一个对象的属性具体的使用是不需要看具体的对象的,属性在哪里声明在哪里使用
        CCC eeeee = new DDDDD();
        System.out.println("new DDDDD()中没有sum方法,执行父类的方法 "+eeeee.sum());

    }
}
class CCC {
    int i = 10;
    int sum() {
        return getI() + 10;
    }
    int getI() {
        return i;
    }
}
class DDD extends CCC {
    int i = 20;
    int sum() {
        return i + 20;
    }
}

class DDDD extends CCC {
    int i = 20;
}
class DDDDD extends CCC {
    int i = 28;

    int getI() {
        return i;
    }
}
图31 子类重写

4.4 多态

【例题19】面向对象 - 多态

package cn.du.ch04;

public class Java13_Object {
    public static void main(String[] args) {

        // TODO 面向对象 - 多态
        // 所谓的多态,其实就是一个对象在不同场景下表现出来的不同状态和形态
        // 多态语法其实就是对对象的使用场景进行了约束
        // 一个对象可以使用的功能取决于引用变量的类型
        System.out.println("面向对象-多态【杜老师整理】");
        Person p = new Person();
        p.姓名 = "杜老师";
        p.散步();

        Person p1 = new Boy();
        p1.姓名 = "张山";
        p1.散步();
        //p1.拳击();  //父类中没有 拳击() 方法 爆红

        Person p2 = new Girl();
        p2.散步();
        p2.姓名 = "李思";
        //p2.绣花();  //父类中没有 绣花() 方法 爆红

        Boy boy = new Boy();
        boy.姓名 = "鲁智深";
        boy.拳击();

        Girl girl = new Girl();
        girl.姓名 = "林黛玉";
        girl.绣花();
    }
}

class Person {
    String 姓名;
    void 散步() {
        System.out.println(姓名+" 在林间小路慢腾腾的走路...");
    }
}
class Boy extends Person {
    void 拳击() {
        System.out.println(姓名+" 在肉铺拳打脚踢镇关西...");
    }
}
class Girl extends Person {
    void 绣花() {
        System.out.println(姓名+"在阁楼上认真仔细地绣花...");
    }
}
图24

【例题20】面向对象 - 多态 - 重载

package cn.du.ch04;

public class Java14_Object {
    public static void main(String[] args) {
        // TODO 面向对象 - 多态 - 重载
        // 一个类中,不能重复声明的相同的方法,也不能声明相同的属性
        // 这里相同的方法指的是方法名,参数列表相同,和返回值类型无关
        // 如果方法名相同,但是参数列表(个数,顺序,类型)不相同,会认为是不同的方法,只不过名称一样
        // 这个操作在Java称之方法的重载
        // 构造方法也存在方法的重载
        System.out.println("面向对象-多态-重载【杜老师改编】");
        User14 user = new User14("杜老师");
        user.login(13903510001l);
        user.login("123123");
        user.login("dzjiang", "123456");
    }
}
class User14 {
    User14() {
        System.out.println("无参构造方法 User14...");
    }
    User14(String 姓名) {
        System.out.println("有参构造方法 User14..." + 姓名);
    }
    void login( String 账号, String 密码登录 ) {
        System.out.println("账号,密码登录");
    }
    void login(long 手机号) {
        System.out.println("手机验证码登录");
    }
    void login(String 微信号) {
        System.out.println("微信,支付宝登录");
    }
}
图26 面向对象-多态-重载

【例题21】面向对象 - 构造方法 - 重载

package cn.du.ch04;

public class Java14_Object_1 {
    public static void main(String[] args) {

        // TODO 面向对象 - 构造方法 - 重载
        System.out.println("面向对象-构造方法-重载【杜老师改编】");
        User140 user1 = new User140();
        System.out.println(user1);
        User140 user2 = new User140("张三");
        System.out.println(user2.姓名);
        User140 user3 = new User140("李思", "男");
        System.out.println(user3.姓名+ "  " + user3.性别);

        // 如果在一个构造方法中。想要调用其他的构造方法,那么需要使用特殊的关键字:this
        User141 user4 = new User141();
    }
}

class User140 {
    String 姓名;
    String 性别;
    User140() {
    }
    User140( String 姓名 ) {
        this.姓名 = 姓名;
    }
    User140( String 姓名, String 性别 ) {
        this.姓名 = 姓名;
        this.性别 = 性别;
    }
}

class User141 {
    User141() {
        this("张山");
    }
    User141( String name ) {
        this(name, "男");
    }
    User141( String name, String sex ) {
        System.out.println(name + "," + sex);
    }
}
图27 面向对象 - 构造方法 - 重载

【例题22】面向对象 - 多态 - 重载练习

package cn.du.ch04;

public class Java14_Object_2 {
    public static void main(String[] args) {
        // TODO 面向对象
        byte b = 10;
        test(b);
        // int => iii
        // byte => 8、 short => 16、 char => 16、 int => 32
        // 基本数据类型在匹配方法时,可以在数值不变的情况下,扩大数据的精度
        // byte类型无法和char类型做转换,char没有负数,但是byte存在负数
    }

    static void test( byte b ) {
        System.out.println("bbb");
    }
    static void test( short s ) {
        System.out.println("sss");
    }
    static void test( char c ) {
        System.out.println("ccc");
    }
    static void test( int i ) {
        System.out.println("iii");
    }
}
图28 面向对象 - 多态 - 重载练习1

【例题23】面向对象 - 多态 - 重载练习

package cn.du.ch04;

public class Java14_Object_3 {
    public static void main(String[] args) {

        // TODO 面向对象-静态方法的重载
        AAA aaa = new AAA();
        BBB bbb = new BBB();
        AAA ccc = new BBB();
        Object ooo = 1;
        test(aaa);
        test(bbb);
        test(ccc);
        test(ooo);
        // 多态其实就是约束了对象的使用场景
        // 方法的重载:方法名相同,参数列表不同(个数,顺序,类型)
        // AAA -> Object
        // BBB -> AAA -> Object
    }
    static void test( AAA a ) {
        System.out.println("aaa");
    }
    static void test( BBB b ) {
        System.out.println("bbb");
    }
    static void test( Object o ) {
        System.out.println("ooo");
    }
}
class AAA {

}
class BBB extends AAA {

}
图29 面向对象-静态方法的重载

【例题27】方法递归

package cn.du.ch04;

public class Java16_Object_Recursion {
    public static void main(String[] args) {

        // TODO 面向对象 - 递归
        // 所谓的递归:方法调用自身,称之为递归方法
        System.out.println("递归方法【杜老师编制】");
        // 1 + 3 + 5 + 7 + 9... + 19
        int result = computeAP( 20 );
        System.out.println("1 + 3 + 5 + 7 + 9... + 19="+result);

        // 阶乘 : 5! => (4,3,2,1) => 5 * 4 * 3 * 2 * 1
        //       0的阶乘为1.
        // 一个大于1的数的阶乘等于这个数乘以这个数减一的阶乘。
        int result2 = computeFactorial(5);
        System.out.println("5! ="+result2);

        // 1. 递归方法应该有跳出的逻辑:StackOverflowError
        // 2. 调用自身时,传递的参数需要有规律
        //  345345 + 4543534 + 32423 + 43423 + 32423
    }
    public static int computeFactorial(int num) {
        if ( num <= 1 ) {
            return 1;
        } else {
            return num + computeFactorial(num - 1);
        }
    }
    public static int computeAP(int num) {
        num = num % 2 == 0 ? num - 1 : num;
        if ( num == 1 ) {
            return 1;
        } else {
            return num + computeAP(num - 2);
        }
    }
}
图32 递归方法

4.5 抽象

【例题29】面向对象 - final修饰

package cn.du.ch04;

public class Java20_Object {
    public static void main(String[] args) {
        // TODO 面向对象 -final Java中提供了一种语法,可以在数据初始化后不被修改,使用关键字final
        // ①final可以修饰变量:变量的值一旦初始化后无法修改
        // ②final可以修饰属性:那么JVM无法自动进行初始化,需要自己进行初始化, 属性值不能发生变化
        //    一般将final修饰的变量称之为常量,或者叫不可变变量
        // ③final可以修饰方法,这个方法不能被子类重写
        // ④final可以修饰类,这样类就没有子类了
        // final不可以修饰构造方法
        // ⑤final可以修改方法的参数,一旦修饰,参数就无法修改。

        final String name = "杜老师";
        //name = "王老师";  // 爆红 ①final可以修饰变量
        System.out.println(name);

        User20 user = new User20("张山");
        System.out.println(user.name);
        // user.sysName = "学籍管理系统";  // 爆红 ②final可以修饰属性,需要自己进行初始化, 属性值不能发生变化
        System.out.println(user.sysName);
    }
}
class User20 {
    public final String sysName = "成绩管理系统" ;
    public String name ;
    public User20() {

    }
    public User20(String name) {
        this.name = name;
    }
    public void test( final String uname ) {
        // uname = "lisi";
        // 爆红 ⑤final可以修改方法的参数,一旦修饰,参数就无法修改。
    }
    public final void test() {

    }
}
class Child20 extends User20 {
    //public void test() {
        // 爆红 ③final可以修饰方法,这个方法不能被子类重写
    //}
}

final class User21 {
    public User21() {

    }
}
//class Child21 extends User21 {
// 爆红 ④final可以修饰类,这样类就没有子类了
//}
图37 final修饰

【例题29】抽象

package cn.du.ch04;

public class Java21_Object_Abstract {
    public static void main(String[] args) {

        // TODO 面向对象 - 抽象 - Abstract
        System.out.println("面向对象-抽象-Abstract【杜老师整理】");
        // 抽象类 : 不完整的类,就是抽象类
        //           abstract class 类名
        //         因为类不完整,所以无法直接构造对象
        // 抽象方法 : 只有声明,没有实现的方法
        //            abstract 返回值类型 方法名(参数)

        // 分析问题:对象(具体) => 类(抽象)
        // 编写代码:类(抽象) => 对象(具体)

        // 如果一个类中含有抽象方法,那么这个类是抽象类
        // 如果一个类是抽象类,它的方法不一定是抽象方法。

        // 抽象类无法直接构建对象,但是可以通过子类间接构建对象
        // 如果抽象类中含有抽象方法,那么子类继承抽象类,需要重写抽象方法,将方法补充完整,

        // abstract关键字不能和final同时使用

        //Person21 p = new Person21();  // 抽象类无法直接构建对象
        Chinese21 c = new Chinese21();
        c.eat();

    }
}

abstract class Person21 {
    public abstract void eat();
    public void test() {

    }
}

class Chinese21 extends Person21 {
    public void eat() {
        System.out.println("中国人使用筷子吃饭");
    }
}
图38 抽象

4.6 接口

抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的“抽象类”——接口(Interface)。接口是Java 中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成。

【例题30】接口 -- 规则

package cn.du.ch04;

public class Java22_Object {
    public static void main(String[] args) {

        // TODO 面向对象 - 接口
        System.out.println("面向对象-接口【杜老师】");
        // 所谓的接口,可以简单理解为规则
        // 基本语法 : interface 接口名称 { 规则属性,规则的行为 }
        // 接口其实是抽象的
        // 规则的属性必须为固定值,而且不能修改。
        // 属性和行为的访问权限必须为公共的。
        // 属性应该是静态的
        // 行为应该是抽象的
        // 接口和类是两个层面的东西
        // 接口可以继承其他接口
        // 类的对象需要遵循接口,在java中,这个遵循,称之为实现(implements),类需要实现接口,而且可以实现多个接口
        Computer c = new Computer();
        Light light = new Light();
        c.usb1 = light;
        Light light1 = new Light();
        c.usb2 = light1;
        c.powerSupply();

    }
}

interface USBInterface {
}

interface USBSupply extends USBInterface {
    public void powerSupply();
}

interface USBReceive extends USBInterface {
    public void powerReceive();
}

class Computer implements USBSupply {
    public USBReceive usb1;
    public USBReceive usb2;

    public void powerSupply() {
        System.out.println("电脑提供能源");
        usb1.powerReceive();
        usb2.powerReceive();
    }
}

class Light implements USBReceive {
    public void powerReceive() {
        System.out.println("电灯接收能源");
    }
}
图39 接口举例之一

【例题31】接口 -- 标准

-----程序功能的功能实现的标准----方法的名字和参数的个数、顺序和类型,可以有众多的实现。

package cn.du.ch04;

/* 此处我们定义或规定了:
  1个常量:sysname  应用系统名称
  4个方法:存款、取款、查询余额、转账 的方法名称和参数个数、类型、顺序
  至于说如何实现,那就看不同的实现者了。
 */
interface I银行 {
    String sysname = "银行: 设置密码、存款、取款、查询余额、转账【杜老师制定】";
    boolean 设置密码(String 账号, String 姓名, String 原密码, String 新密码);
    boolean 存款(String 账号, String 姓名, double 金额);
    boolean 取款(String 账号, String 姓名, String 密码, double 金额);
    double 查询余额(String 账号, String 姓名, String 密码);
}

//创建接口 [I银行存取转账](继承基接口 [I银行]),
// 包含转账方法: 转账(Account 转出账户, Account 转入账户, String 转出密码,double 金额);
interface I银行存取转账 extends I银行 {
    boolean 转账(Account 转出账户, Account 转入账户, String 转出密码,double 金额);
}

class Account implements I银行存取转账 {
    private String 姓名;
    private String 账号;
    private String 密码;
    private String 身份证号;
    private double 余额;

    public Account(){super();};

    public Account(String 账号, String 姓名, String 身份证号, String 初始密码){
        super();
        this.账号 = 账号;
        this.姓名 = 姓名;
        this.身份证号 = 身份证号;
        this.密码 = 初始密码;
        this.余额 = 1;
    }

    public boolean 存款(String 账号, String 姓名, double 金额) {
        if (this.账号.equals(账号) && this.姓名.equals(姓名)) {
            this.余额 += 金额;
            return true;
        } else {
            System.out.println("存款人账号或姓名不正确");
            return false;
        }
     }

    public boolean 取款(String 账号, String 姓名, String 密码, double 金额) {
        if (this.账号.equals(账号) && this.姓名.equals(姓名) && this.密码.equals(密码)) {
            if (this.余额 >= 金额) {
                this.余额 -= 金额;
                return true;
            } else {
                System.out.println("余额不足,取款失败");
                return false;
            }
        } else {
            System.out.println("取款人账号、姓名或密码不正确");
            return false;
        }
    }

    public boolean 设置密码(String 账号, String 姓名, String 原密码, String 新密码) {
        if (this.账号.equals(账号) && this.姓名.equals(姓名) && this.密码.equals(原密码)) {
            this.密码 = 新密码;
            return true;
        } else {
            System.out.println("账号、姓名或原密码不正确");
            return false;
        }
    }

    public double 查询余额(String 账号, String 姓名, String 密码){
        if (this.账号.equals(账号) && this.姓名.equals(姓名) && this.密码.equals(密码)) {
            return this.余额;
        } else {
            System.out.println("账号、姓名或原密码不正确");
            return 0;
        }
    };

    public String get账号() {
        return 账号;
    }

    public String get姓名() {
        return 姓名;
    }

    public String get身份证号() {
        return 身份证号;
    }

    public boolean 转账(Account 转出账户, Account 转入账户, String 转出密码, double 金额) {//银行转账
        boolean result = 取款(转出账户.get账号(),转出账户.get姓名(),转出密码,金额);
        if (result) {
            转入账户.存款(转入账户.get账号(),转入账户.get姓名(),金额);
        }
        return result;
    }

    @Override
    public String toString() {
        return "银行账户[账号:" + 账号 + "  姓名:" + 姓名 + ", 余额=" + 余额 + "]";
    }
}

public class Java22_Object1 {

    public static void main(String[] args) {
        System.out.println(I银行.sysname);
        Account bc1 = new Account("100001","曹操","140101199901010001","123123");
        Account bc2 = new Account("200002","刘备","140411200001010002","123456");
        System.out.println(bc1.toString());
        System.out.println(bc2.toString());
        bc1.存款("100001","曹操",1000);
        bc2.存款("200002","刘备",2000);
        bc2.取款("200002","刘备","123456",200);
        bc2.转账(bc2, bc1, "123456",100);
        System.out.println(bc1.toString());
        System.out.println(bc2.toString());
    }
}
图40 接口举例之二

【例题32】枚举

package cn.du.ch04;

public class Java23_Object_Enum {
    public static void main(String[] args) {

        // TODO 面向对象 - 枚举
        // 枚举是一个特殊的类,其中包含了一组特定的对象,这些对象不会发生改变, 一般都使用大写的标识符,
        // 枚举使用enum关键字使用
        // 枚举类会将对象放置在最前面,那么和后面的语法需要使用分号隔开
        // 枚举类不能创建对象,它的对象是在内部自行创建
        System.out.println("面向对象 - 枚举【杜老师改编】");
        System.out.println("直辖市.京.名称 = "+直辖市..名称);
        System.out.println("直辖市.京.代码 = "+直辖市..代码);
        System.out.println("C直辖市.渝.名称 = "+C直辖市..名称);
        System.out.println("C直辖市.渝.代码 = "+C直辖市..代码);
        System.out.println("政治面貌.中共党员.代码 = "+政治面貌.中共党员.代码);
        System.out.println("政治面貌.中共党员.名称 = "+政治面貌.中共党员.名称);
        System.out.println("政治面貌.民革会员.代码 = "+政治面貌.民革会员.代码);
        System.out.println("政治面貌.民革会员.名称 = "+政治面貌.民革会员.名称);
    }
}

// 使用类实现 枚举 的功能
class C直辖市 {
    public String 名称;
    public int 代码;

    private C直辖市(String 名称, int 代码) {
        this.名称 = 名称;
        this.代码 = 代码;
    }

    public static final C直辖市 京 = new C直辖市("北京", 11);
    public static final C直辖市 津 = new C直辖市("天津", 12);
    public static final C直辖市 沪 = new C直辖市("上海", 31);
    public static final C直辖市 渝 = new C直辖市("重庆", 50);
}

enum 直辖市 {("北京", 11),("天津", 12),("上海", 31),("重庆", 50);
    直辖市( String 名称, int 代码 ) {
        this.代码 = 代码;
        this.名称 = 名称;
    }
    public final String 名称;
    public final int 代码;
}

enum 政治面貌 {
    中共党员("01","中国共产党党员" ),
    中共预备党员("02","中国共产党预备党员" ),
    共青团员("03","中国共产主义青年团团员"),
    民革会员("04","中国国民党革命委员会会员"),
    民盟盟员("05","中国民主同盟盟员"),
    民建会员("06","中国民主建国会会员" ),
    民进会员("07","中国民主促进会会员" ),
    农工党党员("08","中国农工民主党党员"),
    致公党党员("09","中国致公党党员"),
    九三学社社员("10","九三学社社员"),
    台盟盟员("11","台湾民主自治同盟盟员"),
    民主人士("12","无党派民主人士"),
    群众("13","群众");
    政治面貌( String 代码, String 名称 ) {
        this.代码 = 代码;
        this.名称 = 名称;
    }
    public final String 名称;
    public final String 代码;
}
图41 枚举举例

【例题33】匿名类

package cn.du.ch04;

public class Java24_Object {
    public static void main(String[] args) {

        // TODO 面向对象
        // 在模型场合下,类的名字不重要,我们指向使用类中的方法或功能。那么此时我们可以采用特殊的语法:匿名类
        // 所谓的匿名类,就是没有名字的类
        System.out.println("面向对象-匿名类【杜老师改编】");
        Me me = new Me();
        me.sayHello( new Zhangsan() );
        me.sayHello( new Lisi() );
        me.sayHello( new Person24() {
            public String name() {
                return "王五";
            }
        });
        me.sayHello( new Person24() {
            public String name() {
                return "赵六";
            }
        });

        new Bird24().fly();
        new Fly(){
            public void fly() {
                System.out.println("使用飞行器飞翔");
            }
        }.fly();
    }
}

interface Fly {
    public void fly();
}

class Bird24 implements Fly {
    public void fly() {
        System.out.println("使用翅膀飞翔");
    }
}

abstract class Person24 {
    public abstract String name();
}

class Me {
   public void sayHello(Person24 person24) {
       System.out.println("Hello " + person24.name());
   }
}

class Zhangsan extends Person24 {
    public String name() {
        return "张三";
    }
}
class Lisi extends Person24 {
    public String name() {
        return "李四";
    }
}
图42 匿名类举例

【例题34】作用域

package cn.du.ch04;

public class Java26_Object {
    public static void main(String[] args) {

        // TODO 面向对象 - 作用域
        System.out.println("面向对象 - 作用域【杜老师】");
        User26 user = new User26();
        user.test();
        user.test1();
        User26.test1();
    }
}
class Person26 {
    public String name = "张三";
    public static String name1 = "张三静";
}
class User26 extends Person26 {
    public String name = "张小三";
    public static String name1 = "张小三静";

    public void test() {
        String name = "小张三";

        // 如果属性和(局部)变量的名称相同,访问时如果不加修饰符,那么优先访问变量
        System.out.println("父类 super.name = "+super.name);
        System.out.println("自己 this.name = "+this.name);
        System.out.println("局部  name = "+ name);
    }
    public static void test1() {
        System.out.println("Person26.name1 = "+Person26.name1);
        System.out.println("User26.name1 = "+User26.name1);
        System.out.println("name1 = "+name1);
    }
}
图43 面向对象-作用域
图44 ch04 面向对象 源代码文件名截图

返回