Java对象与类1.0

Posted 364.99°

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java对象与类1.0相关的知识,希望对你有一定的参考价值。


1.面向对象程序设计概述

面向对象程序设计(object-oriented programming,OOP)

面向对象的程序是由对象组成,每个对象包含对用户公开的特定功能部分和隐藏的实现部分
相对于其他语言的程序员工作过方式:先确定如何操作数据,再决定如何组织数据的结构,OOP却调换了次序,将数据放在了第一位,然后再考虑操作数据的算法。
面向对象更适合解决规模较大的问题

面向过程与面向独享的程序设计对比:
在这里插入图片描述

1.1.类

关键名词:

类(class):构造对象的模板(蓝图),创建类的实例(instance)
实例(instance):由类构造(construct)对象的过程称为创建类的实例
实例字段(instance field):对象中的数据,特定的对象都有一组特定的实例字段值,这些值得集合就是这个对象当前的状态(state)
方法(method):操作数据的过程
封装(encapsulation,也称数据隐藏):处理对象的一个重要概念:
    从形式上看:将数据和行为组合在一个包中,并对对象的使用者隐藏具体的实现方式
    实现封装的关键:绝不能让类中的方法直接访问其他类的实例字段。程序员只能通过对象的方法与对象数据进行交互(“黑盒”特征,提高重用性和可靠性)
继承(inheritance):通过扩展一个类(属性和方法)来建立另一个类的过程(所有的类都源自与Object类,其他的所有类都是扩展自这个Object类)

1.2.对象

对象的三个主要特性:

行为(behavior):可以对对象完成哪些操作(可以对对象应用哪些方法)
状态(state):当调用某些方法时,对象会如何响应
标识(identity):如何区分具有相同行为与状态的不同对象

1.3.识别类

OOP没有“顶部”,不必从顶部的main函数开始编写程序,应首先从识别类开始,然后再为各个类添加方法

识别的一个简单经验就是在分析问题的过程中寻找名词,而方法对应着动词
如:
在订单处理系统中,有如下名词:
  商品(Item)
  订单(Order)
  送货地址(Shipping address)
  付款(Payment)
  账户(Account)
从这些名词中就可以得到类Item、Order等
查看动词:
  商品被添加到订单中,订单会发货或取消,另外可以对订单完成付款。
其中的添加,发货,取消以及完成付款都要识别出负责完成相应动作的对象。

1.4.类之间的关系

类之间常见的关系

依赖(“uses-a”):A类的方法使用可操纵B类,而B类的变化也可影响到A。这种使用关系是具有偶然性的、临时性的、非常弱,应当尽可能将相互依赖的类减少至最少(减少耦合)
聚合(“has-a”):A类的对象包含了B类的对象
继承(“is-a”):一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)

2.使用预定义类

在Java中,没有类就做不了任何事情。但不是所有的类都表现出面向对象的典型特征,如Math类,可以直接使用Math类的方法,而不需要了解它具体是如何实现。这是由于封装,Math类只封装了功能,不需要隐藏数据,由于没有数据,所以不必考虑创建对象和初始化它们的实例字段,因为没有实例字段。

2.1.对象与对象变量

使用对象,必须先构造对象,并指定其初始状态,接着使用对象方法。

Java中,使用构造器(constructor)构造新实例。
  构造器名字与类名相同,使用关键字new进行构造新对象
  对象可以调用类方法,对象变量则不行
以下使用Date类:

注意:Java中,对象变量并没有包含一个对象,只是引用了一个对象,任何变量的值都是存储在另外一个地方的某个对象的引用。new操作符的返回值也是一个引用。

2.2.LocalDate类

Date类的实例有一个状态:特定的时间点

Java时间是使用距离一个固定时间点的毫秒数表示的,此时间点称为纪元(epoch),具体为UTC(Universal Time Coordinated ,国际协调时间)时间1970年1月1日 00:00:00
Java类库拥有两个类:
  Date类:表示时间点
  LocalDate类:日历表示法表示日期
不能使用构造器来构造LocalDate类的对象,应该使用静态工厂方法(factory method),它会代调用构造器

import java.time.LocalDate;

public class TestDate {
    public static void main(String[] args) {
        LocalDate.now();//构造一个新对象
        LocalDate.of(1999,10,2);//构造一个特定的日期对象
        LocalDate newYearsEve = LocalDate.of(1999,12,31);//将构造的对象保存在一个对象变量中

        //使用LocalDate的方法
        int year = newYearsEve.getYear();
        int month = newYearsEve.getMonthValue();
        int day = newYearsEve.getDayOfMonth();
        System.out.printf("%d年%d月%d日%n",year,month,day);

        LocalDate aThousandDaysLater = newYearsEve.plusDays(1000);//得到一个新的LocalDate
        int year1 = aThousandDaysLater.getYear();
        int month1 = aThousandDaysLater.getMonthValue();
        int day1 = aThousandDaysLater.getDayOfMonth();
        System.out.printf("%d年%d月%d日%n",year1,month1,day1);
    }
}

关键字简介
static LocaDate now()构造一个表示当前日期的对象
static LocalDate of(int year,int month,int day)构造一个表示给定日期的对象
int getYear
int getMonthValue()
int getDayOfMonth()
得当当前日期的年、月、日
DayOfWeek getDayOfWeek()得到当前日期是星期几,作为DayOfWeek类的一个实例返回,调用getValue()取值1~7
LocalDate plusDays(int n)
LocalDate minusDays(int n)
生成当前日期之后或之前n天的日期

2.3.更改器方法与访问器方法

更改器方法会将原对象的属性值改变,而访问器方法(如plusDays)会创建一个新的对象来存储得到的数值,而不改变原对象的属性值

3.用户自定义类

最简单的类定义形式:

class ClassName{
    field1;
    filed2;

    constructor1;
    constructor2;

    method1;
    method2;

}

自定义一个简单的HolidayLife类

import java.time.LocalDate;

class HolidayLife {
    //instance fields
    private int days;//private:访问修饰符,仅本类可以访问
    private LocalDate date;
    private int studyTime;
    private int workoutTime;

    //constructor(默认自带一个无参构造器)
    //带一个参数的构造器(本案例中并没使用,只是写写)
    public HolidayLife(int days){
        this.days = days;//this表示此对象
    }
    //带四个参数的构造器
    public HolidayLife(int days,LocalDate date,int studyTime,int workoutTime){
        this.days = days;
        this.date = date;
        this.studyTime = studyTime;
        this.workoutTime = workoutTime;
    }

    //method
    public int getDays(){
        return days;
    }
    public LocalDate getDate(){
        return date;
    }
    public int getStudyTime(){
        return studyTime;
    }
    public int getWorkoutTime(){
        return workoutTime;
    }
}

OnHoliday

import java.time.LocalDate;

public class OnHoliday {
    public static void main(String[] args) {
        //声明一个对象数组
        HolidayLife []holiday = new HolidayLife[5];
        //设置假期起始日
        LocalDate date = LocalDate.of(2021,5,1);

        //设置对象数组的内容(利用带参的构造方法实例化5个对象)
        for (int i = 0;i < holiday.length;i++){
            holiday[i] = new HolidayLife(1,date.plusDays(i),(int)(2+Math.random()*5),(int)(1+Math.random()*5));
        }

        //输出假期内容
        String str = "%tF,第%d天假期,学习时长%d时,锻炼时长%d时%n";
        for (HolidayLife each : holiday){
            System.out.printf(str,each.getDate(),each.getDays(),each.getStudyTime(),each.getWorkoutTime());
        }

    }
}

输出结果

3.1.构造器

构造器与类同名,在构造类的对象时,构造器会运行,从未将实例字段初始化为所希望的初始状态(初始化构造器中的参数)
构造器结合new运算符来调用
每个类有一个或以上的构造器
构造器的参数数量不定
构造器没有返回值
不能对一个已经存在的对象使用构造器来重新设置实例字段

3.2.使用null引用

一个对象性变量可包含一个对象的引用,或一个特殊值null,null表示没有引用任何对象

注意: 如果对null值应用一个方法,会抛出NullPointerException异常
这是一个很严重的错误,类似于“索引越界”异常,当程序没有“捕获”异常,程序就会终止。
定义一个类,需要知道哪些字段可能为null


当调用构造器时为days提供的实参为null时,有以下解决方法
    1.“宽容型”方法:将null参数转换为一个适当的非null值
    if (days == null) days = null;else days = n;
    2.“严格型”方法(Java9):直接拒绝null参数

    public HolidayLife(int days,LocalDate date,int studyTime,int workoutTime){
        Objects.requireNonNull(days,"The days can't be null");//拒绝days为null
        this.days = days;
        this.date = date;
        this.studyTime = studyTime;
        this.workoutTime = workoutTime;
    }

3.3.隐式参数与显示参数

隐式参数(implicit):出现在方法名前的类的对象,没有出现在方法声明中
显示参数(explicit):位与方法名后括号中的数值,显示地出现在方法声明中
this:在方法中指示隐式参数

3.4.封装

封装: 将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问

优点: 可以改变内部实现,而除了该类的方法外,不会影响其他代码
       更改器方法可以完成错误检查

实现: 一个私有化的数据字段,修改属性的访问权限为private
       一个公共的访问器方法,创建getter方法
       一个公共的字段更改器方法,创建setter方法

注意: 不要编写返回可变对象引用的访问其方法,会破坏封装性
需要返回一个可变对象的引用,需要对它进行克隆(clone方法)

3.5.访问权限

类型本类同包子类不同包子类同包类其他类
public可访问可继承可继承可访问可访问
protected可访问可继承可继承可访问不可访问
package可访问可继承不可继承可访问不可访问
private可访问不可继承不可继承不可访问不可访问

3.6.私有方法

在实现一个类时,由于公共数据非常危险,所以应当将所有的数据字段都设置为私有的。
虽然大多数方法都被设置为公共的,但在某些特殊情况下,将方法设置为私有的很有用

实现: 使用private将方法声明为私有
优点: 只要方法是私有的,类的设计者就可以确信它不会再别处使用,所以可以将其删去。如果是一个公有方法,就不能简单地将其删除,因为有可能有其他代码依赖这个方法。

3.7.final实例字段

将实例字段定义为final,这样的字段必须在构造对象时初始化(即确保在每一个构造器执行之后,这个值已经设置),并且之后不能再修改这个字段
对于类型为基本类型或者不可变类的字段尤其有用


以上是关于Java对象与类1.0的主要内容,如果未能解决你的问题,请参考以下文章

Java——面向对象与类

对象与类

第三周学习《对象与类》心得

Java对象与类

java学习笔记(Core Java)4 对象与类

Java--对象与类