6、对象构造

重载:如果有多个方法(比如,StringBuilder构造器方法)有相同的名字、不同的参数、便产生了重载。

重载解析:编译器通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配来挑选出相应的方法。如果编译器找不到匹配的参数, 就会产生编译时错误,因为根本不存在匹配, 或者没有一个比其他的更好。

签名(signature):Java允许重载任何方法,因此,要完整的描述一个方法需要指出方法名以及参数类型。

返回类型不是签名的一部分。也就是说,不能有两个名字相同、参数类型也相同的却返回不同类型值的方法。

默认域初始化:如果在构造器中没有显式地给域赋予初值,那么就会被自动地赋为默认值:数值为0、布尔值为false、对象引用为null

无参数的构造器:顾名思义,没有参数的构造器。假如一个类中没有任何构造器,那么系统会默认提供一个无参数构造器。这个构造器将所有的实例域设置为默认值,即数值为0、布尔值为false、对象引用为null。如果一个类中提供了构造器,但是没有提供无参数的构造器,则在构造对象时如果没有提供参数就会被视为不合法。

public Employee()
{}

显式域初始化:显式地直接赋一个值,确保不管怎样调用构造器每个实例域都可以被设置为一个有意义的初值。好的设计习惯。适用于当一个类的所有构造器都希望把相同的值赋给某个特定的实例域时。

public class Employee {
// instance field 实例域
private String name = "";
private double salary = 0.0;
private LocalDate hireDay = new LocalDate(); // 也可以调用函数
}

参数名:参数变量用同样的名字将实例域屏蔽起来。可以采用 this.salary 的形式访问实例域。this 指示隐式参数, 也就是所构造的对象。

public Employee(String name, double salary)
{
this.name = name; // 如果用name = name,就不会把参数变量传递给实例域。因为局部变量与实例域同名会屏蔽实例域
this.salary = salary;
}

调用另一个构造器:如果一个构造器的第一个语句如this(...),这个构造器将调用同一个类的另一个构造器。关键字this有两个含义,一个是引用方法的隐式参数,另一个是加上括号后表示类的构造器方法。

public Employee(String name, double salary)
{
this.name = name;
this.salary = salary;
}
public Employee(double s)
{
// calls Employee (String, double)
this("Bob", s);
}
// 采用这种方法使用this关键字非常有用,这样对公共的构造器代码部分只编写一次即可。

初始化块:在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行。

这种机制不是必须的,也不常见。通常会直接将初始化代码放在构造器中。即使在类的后面定义,仍然可以初始化块中的设置域,但是推荐将初始化块放在域定义之后。

public class Test6 {
private static int nextId; private int id;
private String name;
private double salary; // 对象初始化块 大括号包裹的语句 在执行构造函数之前执行
{
id = nextId;
nextId ++;
} public Employee(String n, double s)
{
name = n;
salary = s;
}
public Employee()
{
name = "";
salary = 0;
}
// ...
}

静态的初始化块:对类的静态域进行初始化的代码比较复杂。

static
{
Random generator = new Random();
nextId = generator.nextInt(1000); // 生成一个随机数[0~999] int
}

实际应用

import java.util.Random;

public class ConstructTest {
public static void main(String[] args) {
// fill the staff array with three Employee objects
Employee1[] staff = new Employee1[3]; staff[0] = new Employee1("Harry", 40000);
staff[1] = new Employee1(60000);
staff[2] = new Employee1(); // print out information about all Employee objects
for(Employee1 e : staff)
{
System.out.println("name=" + e.getName() + ",id=" + e.getId() + ", salary=" + e.getSalary());
}
}
}
class Employee1
{
private static int nextId; private int id;
private String name = ""; // 实例域初始化
private double salary; // 静态初始化块
static
{
Random generator = new Random();
nextId = generator.nextInt(1000); // 生成一个随机数[0~999]
}
// 初始化块
{
id = nextId;
nextId++;
}
// 重载构造器
public Employee1(String n, double s)
{
name = n;
salary = s;
} public Employee1(double s)
{
this("Employee #" + nextId, s);
}
// 默认构造器
public Employee1()
{
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public int getId()
{
return id;
}
}
/*
name=Harry,id=391, salary=40000.0
name=Employee #392,id=392, salary=60000.0
name=,id=393, salary=0.0
*/

对象析构与finalize方法:

  • 由于有自动的垃圾回收器,所以Java不支持析构器。

  • 可以为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象之前调用。在实际应用中,不要依赖于使用finalize方法回收任何短缺的资源,这是因为很难知道这个方法什么时候才能够调用。

总结

  1. 调用构造器的具体处理步骤:

    1. 所有数据域被初始化为默认值(0,false,null)
    2. 按照类声明中出现的次序,依次执行所有域初始化语句初始化块
    3. 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体。
    4. 执行这个构造器的主体。
  2. 三种初始化数据域的方法:
  • 在构造器中设置值
  • 在声明中赋值
  • 初始化块赋值

7、包

包:方便地组织自己的代码,并将自己的代码与别人提供的代码库分开管理。

使用包的主要原因是确保类名的唯一性。

为了保证包名的绝对唯一性,Sun公司建议将公司的因特网域名(这显然是独一无二的)以逆序对的形式作为包名,并且对于不同的项目使用不同的子包。

类的导入:一个类可以使用所属包中的所有类,以及其他包中的公有类(public class)

访问其他包中的共有类的两个方法:

  • 在每个类名之前添加完整的包名

    java.time.LocalDate today = java.time.LocalDate.now();
  • 使用import语句

    import java.util.*; // 导入全部类,对代码的大小也没有任何负面影响
    LocalDate today = LocalDate.now(); import java.util.LocalDate; // 或者导入特定类

静态导入:import 语句不仅可以导入类,还增加了导入静态方法和静态域的功能。

import static java.lang.System.*; // 导入静态方法和静态域,使用时不用加类名前缀
out.println("123"); // System.out.println()
exit(0); // System.out.exit()

将类放入包中

要想将一个类放入包中,就必须将包的名字放在源文件的开头,包中定义类的代码之前。

package com.horstmann.corejava;
public class Employee
{
...
}

如果没有在源文件中放置package语句,这个源文件中的类就被放置在一个默认包defaulf package)中。默认包是一个没有名字的包。在此之前,我们定义的所有类都在默认包中。

如果包与目录不匹配,虚拟机就找不到类。

包作用域

修饰符可以访问的位置

public公开:任何位置可以访问

protected保护:同包、子类、本类可以访问

缺省:本类、同包可访问

private私有:本类中可访问

8、类路径

类存储在文件系统的子目录中。类路径必须与包路径匹配。

类文件也可以存储在JAR文件中。JAR文件使用ZIP格式组织文件和子目录。可以使用所有ZIP实用程序查看内部的rt.jar以及其他的JAR文件。

为了使类能够被多个程序共享,需要做到以下几点

  1. 把类放到一个目录中,例如/home/user/classdir。需要注意,这个目录是包树状结构的基目录。如果希望将qwe/wer/ert/ConstructTest类添加到其中,这个class类文件就必须位于子目录中/home/user/classdir/qwe/wer/ert中。
  2. 将JAR文件放在一个目录中,例如/home/user/classdir
  3. 设置类路径(class path)。类路径是所有包含类文件的路径的集合。

9、文档注释

JDK包含一个很有用的工具,叫做javadoc,它可以由源文件生成一个HTML文档。

使用:在源代码中添加专用的定界符/**开始的注释,会自动生成文档。

JavaSE 对象与类(二)的更多相关文章

  1. JavaSE基础(十二)--Java 对象和类

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例(对象不是找个女朋友 ...

  2. Python-面向对象(类)二

    一.成员修饰符 • 共有成员 • 私有成员 __+字段 __:成员修饰符 无法直接访问,只能通过该成员所属类的方法简介访问 class Foo: def __init__(self, name, ag ...

  3. JavaSE 学习笔记02丨对象与类

    Chapter 4. 对象与类 4.1 面向对象程序设计概述 面向对象程序设计(简称OOP),是当今主流程序设计范型.面向对象的程序是由对象组成的,每个对象(来自于标准库或自定义的)包含对用户公开的特 ...

  4. Java 读书笔记 (二) 对象和类

    Java 作为一种面向对象语言,支持以下基本概念: 多态 继承 封闭 抽象 类 对象 实例 方法 重载 对象: 是类的一个实例,有状态和行为.以人为例,黄种人.白种人.黑种人为类,每一个具体的人为类的 ...

  5. java基础(二) -对象和类

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一 ...

  6. Java匹马行天下之JavaSE核心技术——工具类

    Java匹马行天之JavaSE核心技术——工具类 一.Object类 java.lang.ObjectObject类是所有类直接或间接的父类 常用的方法: toString():以字符串形式返回对象的 ...

  7. [002] - JavaSE面试题(二):基本数据类型与访问修饰符

    第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [002] - JavaSE面试题(二):基本数据类型与访问修饰符 第1问:Java的数据类型有哪 ...

  8. Python-面向对象(类)一

    一.如何创建类 class cls: pass 二.创建方法 构造方法: __init__(self, arg) obj = 类('a1') 普通方法: obj = 类('xxx') obj.普通方法 ...

  9. CoreJava学习笔记1-基本概念、对象和类

    一.    java的基本程序设计结构 (一)   java共有8种基本类型:4种整型,2种浮点类型,1种char,1种boolean. 1)       4种整型:byte(1).short(2). ...

  10. XML转换为对象操作类详解

    //XML转换为对象操作类 //一,XML与Object转换类 using System.IO; using System.Runtime.Serialization.Formatters.Binar ...

随机推荐

  1. iNeuOS工业互联网操作系统,脚本化实现设备运行时长和效率计算与统计

    目       录 1.      概述... 2 2.      实时采集开停状态... 2 3.      增加虚拟设备... 2 4.      脚本统计和计算设备运行时长... 4 5.    ...

  2. Python3.7.3安装TensorFlow和OpenCV3

    根据python的版本进行下载相应的文件 一.安装TensorFlow 进入网址https://pypi.org/project/tensorflow/#files下载TensorFlow文件 进入下 ...

  3. 1.3 Apache Hadoop的重要组成-hadoop-最全最完整的保姆级的java大数据学习资料

    目录 1.3 Apache Hadoop的重要组成 1.3 Apache Hadoop的重要组成 Hadoop=HDFS(分布式文件系统)+MapReduce(分布式计算框架)+Yarn(资源协调框架 ...

  4. Kafka教程(一)基础入门:基本概念、安装部署、运维监控、命令行使用

    Kafka教程(一)基础入门   1.基本概念   背景   领英->Apache   分布式.消息发布订阅系统   角色   存储系统   消息系统   流处理平台-Kafka Streami ...

  5. 使用python脚本传递参数:(三种方式可收藏)

    背景:使用python脚本传递参数在实际工作过程中还是比较常用,以下提供了好几种的实现方式: 一.使用sys.argv的数组传入说明:使用sys.argv必须按照先后的顺序传入对应的参数:sys.ar ...

  6. PyTorch复现LeNet-5手写识别学习笔记

    用PyTorch搭建LeNet-5手写识别 首先申明,这篇博客用于记录本人看完LeNet-5论文,并对其中的算法进行复现的记录,可以看成是学习笔记 这里只介绍复现的工作,如果想了解更多有关网络的细节, ...

  7. JavaScript:对象:如何读取、添加、删除对象的属性?

    如何给对象添加属性? 直接对象名.属性名去添加属性 直接对象名[属性名]去添加属性,此时属性名得是字符串类型,可以直接引号,也可以用变量名 如何读取对象的属性值? 这个操作,和添加属性是一样的,即用点 ...

  8. [编程基础] Python命令行解析库argparse学习笔记

    Python argparse教程展示了如何使用argparse模块解析Python中的命令行参数. 文章目录 1 使用说明 1.1 Python argparse可选参数 1.2 Python ar ...

  9. vsftp安装文档

    vsftp安装文档 张京坤 20190325 ftp安装 安装环境:centOS7.6 安装vsfptd 在线安装:服务器联网状态下 检查是否安装了vsftpd:rpm -qa |grep vsftp ...

  10. 浅谈LCA问题(最近公共祖先)(四种做法)

    [模板]最近公共祖先(LCA) \(update \ 2023.1.3\) 新增了树链剖分 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入格式 第一行包含三个正整数 \ ...