Java学习-04 面向对象以及快递管理案例练习

本文介绍了Java面向对象的概念,强调从面向过程到面向对象的思维转变。文章深入探讨了匿名对象、静态特性的用法,包括静态方法的调用和静态变量的访问规则。同时,讲解了main方法、继承、构造器重载、重写与重载的区别、抽象类的使用原则,以及异常处理和递归的基础知识。最后,通过一个快递管理案例,实践了面向对象编程,总结了面向对象编程的优点和注意事项。
摘要由CSDN通过智能技术生成

Java学习-04 面向对象

这阵子主要学习了Java的面向对象。面向对象是相对于面向过程来讲的,从面向过程到面向对象,是程序员思想上从执行者到指挥者的转变。面向对象强调的是直接以现实中的事物,也就是对象,为中心来思考,认识问题,并根据它们各自的本质特点(共性),把它们抽象为java中的类,这样的方式与现实世界有着更好的映射,而且也更符合人类的思维习惯。

想学好面向对象,光靠看听是远远不够的,一个合格的程序员同时也是一个辛勤的耕耘者,一定要多写代码,只有在练习的过程中,才会去想这个地方怎么做,用什么做,怎么优化,遇到问题是不可避免的,但也是问题让我们对于每一个问题背后的知识点掌握的更加深刻。接下来就结合具体的例子说一说我学习中遇到的知识点。

1、匿名对象

我们现在有一个 Person类,它有名字和年龄两个属性,还有一个可以输出姓名年龄的say方法。下边这个代码将会输出什么?

new Person().name = "张三";
new Person().age = 18;
new Person().say();
// 这三个是毫无关系的三个对象

它不会输出 张三 和 18,而是输出Person类的默认值。因为,每一次new都相当于在堆内存中新建一个新的对象,而这个对象如果没有指向它的引用,它最多可以使用一次,这就是匿名对象了,可以类比匿名信,只能和写信的人存在这一次交流,然后你就找不到他了。所以,前两行的代码,在程序执行到第三行的时候就已经找不到了,所以say输出的就是默认值。

2、静态

静态修饰的方法,被调用时,有可能对象还未创建

被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访

问。并且不会因为对象的多次创建, 而在内存中建立多份数据。

相关使用:static 可以用来修饰 这个类都具有同一个值的属性,这样方便直接修改。

在访问时: 静态不能访问非静态 , 非静态可以访问静态 !因为静态加载完毕的时候,非静态可能还没有加载到内存中。

静态代码块只会在类加载时执行一次,而构造代码块在每次创建对象时都会执行,且在构造方法之前。

面试题:

构造方法 与 构造代码块 以及 静态代码块的执行顺序:

静态代码块 --> 构造代码块 --> 构造方法

3、main方法

main()方法是程序的入口,程序从这里开始执行:
public static void main(String args[])
以上的各个参数的含义如下:
· public:表示公共的内容,可以被所有操作所调用
· static:表示方法是静态的,可以由类名称直接调用。java StaticDemo09
· void:表示没有任何的返回值操作
· main:系统规定好的方法名称。如果main写错了或没有,会报错:NoSuchMethodError: main
· String[] args:字符串数组,接收参数的

演示:测试这段代码

public class Test {
   
    public static void main(String[] args) {
   
        for (String arg : args) {
   
            System.out.println(arg);
        }
    }

String[] args 接收命令参数,什么也不输入,就什么也不输出,输入数字什么的,要用空格隔开,接收进来的就是一个字符串数组。
在这里插入图片描述
对于本来就有空格的字符串,要用" "括起来,才能输出你想要的:
在这里插入图片描述

否则,输出的就是按空格分割的单词:
在这里插入图片描述

4、继承

java只有单继承。

内存图:

在这里插入图片描述

super 保存父类地址,所以可以用它调用父类的东西,因为它就相当于父类的引用。

5、构造器重载

回顾了构造器重载,以及使用this来减少代码的重复,使用this调用另一个重载的构造器只能在构造器中使用,而

且必须作为构造器执行体的第一条语句。

为什么要用this来调用另一个重载的构造器?
在这里插入图片描述

如图,这种情况,我们就可以使用this调用构造器A,而不用在B,C,D中都写上重复的代码了。使用this的好处

是,如果有一天我们需要对构造器A中的代码进行修改时,如果B,C,D甚至更多的构造器中不是用的this,而是

和A一样的代码,也需要修改,那么工程量就很大了,用this的话,就只需要修改A中代码即可。这样可以充分的利

用每一段代码,既可以让程序简洁,也降低了维护成本。

6、重写以及与重载的区别

面试题:
Java中重写(Override)与重载(Overload)的区别
	1、发生的位置
        重载:一个类中
        重写:子父类中
	2.参数列表限制
        重载:必须不同的
        重写:必须相同的
	3、返回值类型
        重载:与返回值类型无关
        重写:返回值类型必须一致
	4、访问权限:
        重载:与访问权限无关
        重写:子类的方法权限必须不能小于父类的方法权限
	5、异常处理:
        重载:于异常无关
        重写:异常范围可以更小,但是不能抛出新的异常。

7、抽象类

抽象类就像一个大纲。抽象,顾名思义,就是不够具体,也就是说,只有一个大概。那么抽象类和抽象方法,也就是这么一个意思,我们知道大概要有这么个东西,但是呢,没办法在当时就立马完全的把所有细节搞定,因此先写个抽象类,抽象方法,类似于论文的大纲,大概那么个东西,后期可能还会修改,把它具体化。

在抽象类的使用中有几个原则:

  • 抽象类本身是不能直接进行实例化操作的,即:不能直接使用关键字new完成。
  • 一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须重写抽象类中的全部抽象方法。

一些容易出错的概念:

1、 抽象类能否使用final声明?
不能,因为final属修饰的类是不能有子类的 , 而抽象类必须有子类才有意义,所以不能。
2、 抽象类能否有构造方法?
能有构造方法,而且子类对象实例化的时候的流程与普通类的继承是一样的,都是要先调用父类中的构造方法(默
认是无参的),之后再调用子类自己的构造方法。

8、异常处理

在java中,异常可以两类:

  • 受检异常:在编译过程中就可以检查到的异常,这类需要直接处理
  • 运行时异常:在运行时,因为某些因素才会出现的异常,比如要求输入的是数字,但是用户输入了字母,就会出现异常。
异常处理常见面试题
1. try-catch-finally 中哪个部分可以省略?
答: catch和finally可以省略其中一个 , catch和finally不能同时省略
注意:格式上允许省略catch块, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写代码.

2. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
答:finally中的代码会执行
详解:
执行流程:
1. 先计算返回值, 并将返回值存储起来, 等待返回
2. 执行finally代码块
3. 将之前存储的返回值, 返回出去;
需注意:
1. 返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变
2. finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是try或catch中的值
3. 如果在try或catch中停止了JVM,则finally不会执行.例如停电- -, 或通过如下代码退出 JVM:System.exit(0);

9、递归

递归的一般要求:

  • 要有出口,不然会死循环。
  • 一个大问题的解可以由它的小问题的解给出,并能不断地缩小问题规模。

递归的应用很广泛,解决问题的思路也很符合我们人类的思维习惯,就是不断的简化问题,直到我们能够直接解决。对于树结构来说,递归遍历是经常性的操作。

递归可以解决的一些问题:斐波那契数列,汉诺塔问题等等。

一般来说,采用递归的时候,最好画出递归树,这样便于观察是否有大量的冗余计算。

递归的格式决定了它会占用大量的栈内存,因此能不用就不用。

10、面向对象案例练习

案例要求:

快递管理案例:
1.管理员
    - 快递录入
        - 柜子位置(系统产生,不能重复)
        - 快递单号(输入)
        - 快递公司(输入)
        - 6位取件码(系统产生,不能重复)
    - 删除快递(根据单号)
    - 修改快递(根据单号)	
    - 查看所有快递(遍历)
2.普通用户
    - 取快递:输入取件码:显示快递的信息和在哪个柜子中,从柜子中移除这个快递

我的代码描述:

View                视图类,主要负责在控制台打印显示提示
Express             快递类,主要定义快递
ExpressData         快递信息类,主要负责对快递的操作
ExpressManagement   主要负责细节逻辑调度
AdministratorClient 管理员客户端,主要用于管理员的各项操作
UserClient          用户客户端,负责取件操作
Main                负责整体逻辑

Main.java

public class Main {
   
    public static void main(String[] args) {
   
        // 创建管理实例
        ExpressManagement expressManagement = new ExpressManagement();
        // 初始化
        expressManagement.initial();
        // 管理
        expressManagement.management();
    }
}

ExpressManagement.java

public class ExpressManagement {
   
    // 视图
    View v;
    // 快递柜
    ExpressData expressData;
    // 用户类
    UserClient user;
    // 管理员类
    AdministratorClient administrator;

    /**
     * 初始化视图和快递柜
     */
    public void initial(){
   
        v = new View();
        expressData = new ExpressData();
        // 欢迎视图
        v.welcome();
    }

    /**
     * 快递管理
     */
    public void management(){
   
        w:while(true){
   
            int IDCommand = v.identityView();
            switch (IDCommand){
   
                // 管理
                case 1: {
   
                    // 得到身份验证视图返回的验证信息
                    String[] messages = v.authenticationView();
                    // 账号
                    String account = messages[0];
                    // 密码
                    String password = messages[1];
                    // 初始化管理员客户端
                    administrator = new AdministratorClient(v, expressData);
                    // 验证
                    if (administrator.authentication(account, password)) {
   
                        v.authenticationSuccess();
                        // 管理快递
                        administrator.management();
                    } else {
   
                        v.authenticationFail();
                    }
                    break;
                }
                // 取件
                case 2: {
   
                    // 用户取件客户端
                    user = new UserClient(v, expressData);
                    // 取件
                    user.getExpress();
                    break;
                }
                // 退出
                case 0 :
                    break w;
            }
        }

        // 拜拜视图
        v.bye();

    }


}

ExpressData.java

import java.util.Arrays;
import java.util.Random;

/**
 * 快递数据类,主要负责快递数据的存入,删除,更改
 */
public class ExpressData {
   
    // 快递柜大小为 10 * 10
    private final Express[][] expresses = new Express[10][10];
    // 定义一个 count 用来记录存储了多少快递
    private int count = 0;
    // 实例化一个随机器,用来随机生成快递存储位置和取件码
    private final Random random = new Random();

    public ExpressData() {
   }

    /**
     * 用来往快递柜添加快递
     * @param express:快递
     * @return 是否添加成功
     */
    public boolean add(Express express){
   
        // 快递满了就直接返回
        if (count == 100){
   
            return false;
        }

        int row;
        int column;
        // 随机生成快递存储位置,一定有位置
        while(true){
   
            row = random.nextInt(10);
            column = random.nextInt(10);
            // 判断随机生成的位置是否有快递
            if(expresses[row][column] 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值