前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java中的对象是什么?【Programming】

Java中的对象是什么?【Programming】

作者头像
Potato
修改2019-11-18 11:59:24
7330
修改2019-11-18 11:59:24
举报

Java的面向对象编程方法几乎是该语言所有内容的基础。下面是你不容错过的内容。

图片来源:Pixabay. CC0.
图片来源:Pixabay. CC0.

Java是一种面向对象的编程语言,它将世界视为具有属性和行为的对象的集合。面向对象 的Java版本非常简单,它几乎是该语言所有内容的基础。 因为它对Java太重要了,所以我将对一些可以帮助该语言新手的内容进行一些解释。

继承

一般来说,所有笛卡尔坐标系的几何对象,如圆、正方形、三角形、直线和点,都具有基本的性质,如位置和延伸。 零扩展的对象,比如点,通常没有更多的内容。 像直线这样的对象有更多对象,例如,一条直线段的起始点和终结点或者一条直线上的两个点(如果它是一条“真直线”)。诸如正方形或三角形之类的对象还有更多的东西(例如拐角点),而圆形可能具有中心和半径。

我们可以看到这里有一个简单的层次结构在起作用: 一般的几何对象可以扩展成特定的几何对象,如点、线、正方形等。 每一个特定的几何对象都继承了位置和延伸的基本几何属性,并添加了自己的属性。

这是单一继承的一个例子。 Java 最初的面向对象模型只允许单一继承,其中对象不能属于多个继承层次结构。 这种设计决策源于程序员发现自己在复杂的多重继承场景中所面临的各种模糊性,通常是“有趣的设计决策”导致了层次结构中函数 foo ()的定义(和重新定义),使它拥有好几种可能实现的情况。

从Java 8开始,就已经有了一个有限的多重继承结构,该结构要求代表程序员进行特定的操作以确保没有歧义。

强类型和静态类型

JAVA是强类型和静态类型的,这意味着什么?

静态类型语言是一种在编译时就知道变量类型的语言。 在这种情况下,不可能将B类型的值分配给声明类型为A的变量,除非存在将B类型的值转换为A类型的值的转换机制。转换将整数值(例如1、2或42)转换为浮点值(例如1.0、2.0或42.0)。

强类型语言自动应用的类型转换非常少(或者可能没有)。 例如,尽管强类型语言可能允许将整数自动转换为实数,但它永远不会允许将实数自动转换为整数,因为这种转换通常需要舍入或截断。

基本类型、类和对象

Java 提供了许多基本类型: byte (8位有符号整数);short (16位有符号整数);int(32位有符号整数);long(64位有符号整数);float(单精度32位浮点数);IEEE double(双精度64位浮点数); boolean(真或假);以及 char(16位 Unicode字符)。

除了这些基本类型之外,Java 还允许程序员使用类声明创建新类型。类声明用于定义对象模板,包括它们的属性和行为。一旦声明了一个类,通常可以使用 new 关键字创建该类的实例。 这些实例直接对应于我们所讨论的“对象”。Java 提供了一个有用的类定义库,包括一些简单的基本类,比如 String,它用于保存一系列字符,比如“ Hello,world”。

让我们定义一个简单的消息类,它包含发送者的名字和消息文本:

class Message {
 String sender;
 String text;
 public Message(String sender, String text) {
 this.sender = sender;
  this.text = text;
 }
}

在这个类声明中需要注意以下几点:

  1. 按照惯例,该类始终以大写字母声明。
  2. Message类包含两个属性(或字段):

–一个名为sender的String字段

–一个名为text的字符串字段

按惯例属性或字段始终以小写字母声明。

  1. 从public Message开始有某种事情。

–这是一种方法 (方法定义对象的行为)。

–用于构造 Message类的实例。

–构造方法的名称始终与类相同,并且应理解为构造后将返回该类的实例。

–其他方法始终以小写字母开头。

–此构造函数是”public”,表示任何调用者都可以访问它。

  1. 作为构建过程的一部分,一些行从this开始。

–this指该类的当前实例。

–因此, this.sender引用对象的sender属性。

–而sender是指Message构造函数方法的参数。

–因此,这两行将对构造函数的调用中提供的值复制到对象本身的字段中。

因此,我们有了Method类的定义。 我们如何使用它?

Message message = new Message ( "system" , "I/O error" ) ;

这里我们看到:

声明Message 类型的变量message。

创建 Message 类的新实例,sender设置为“system”,text设置为“I/O error”。

将 Message 的新实例分配给变量 message。

如果在后面的代码中,给变量message分配了一个不同的值(Message 的另一个实例) ,并且没有创建引用该Message实例的其他变量,那么这个实例不再由任何东西使用,可以被回收。

我们现在可以使用这个变量; 例如,我们可以打印 sender 和 text 属性中的值,如下所示:

System.out.println("message sender = " + message.sender);
System.out.println("message text = " + message.text);

这是一个非常简单的类定义。 我们可以通过以下几种方式修改这个类的定义:

  1. 通过在声明前使用关键字 private,我们可以使属性的实现细节对调用方不可见,从而允许我们在不影响调用方的情况下更改实现。
  2. 如果我们选择在类中隐藏属性,那么我们通常会定义getting和setting,按照 Java 的惯例,它们定义为:
public String getSender()
public String getText()
public void setSender(String sender)
public void setText(String text)
  1. 在某些情况下,我们可能希望具有“只读”属性; 在这种情况下,我们不会为此类属性定义setters
  2. 通过使用private关键字而不是public,可以使调用者看不到该类的构造函数。 当我们有另一个类负责创建和管理消息池(可能在另一个进程甚至在另一个系统中执行)时,我们可能希望这样做。

现在,假设我们需要一种消息来记录它生成的时间。 我们可以这样声明:

class TimedMessage extends Message {
 long creationTime;
 public TimedMessage(String sender, String text) {
 super(sender, text);
 this.creationTime = System.currentTimeMillis();
 }
}

这里我们看到了一些新的东西:

  1. TimedMessage 扩展了Message类也就是说, TimedMessage正在继承Message的属性和行为。
  2. 构造函数在其父类或父类中调用构造函数,并将sender和text的值作为super(sender,text)传入,以确保正确继承其继承的属性。
  3. TimedMessage添加了一个新属性creationTime ,并且构造函数将其设置为当前系统时间(以毫秒为单位)。
  4. 在Java中,以毫秒为单位的时间保持为长(64位)值(0为1970年1月1日UTC)。
  5. 顺便说一句,名称creationTime暗示它应该是只读属性,也暗示其他属性是只读的。也就是说,TimedMessage 实例可能不应该被重用,其属性也不应该被更改。

Object 类

“对象类”听起来有点自相矛盾,不是吗? 但请注意,我们定义的第一个类 Message 似乎没有扩展任何内容,但它确实扩展了。 所有没有特别扩展另一个类的类都将类 Object 作为它们的直接且唯一的父类; 因此,所有类都将 Object 类作为它们的最终超类。

你可以在 Java 的文档中了解更多关于 Object 类的信息。 让我们(简单地)回顾一些有趣的细节:

  1. Object具有构造函数Object() ,即没有参数。
  2. Object为其所有子类提供了一些有用的方法,包括:

– clone() ,它创建并返回当前实例的副本

– equals(Object anotherObject) ,它确定anotherObject是否等于当前的Object实例。

– finalize() ,用于在不再使用实例时对其进行垃圾回收(请参见上文)

– getClass() ,该类返回用于声明当前实例的类。

—由此返回的值是Class类的实例, 该类允许在运行时学习声明类(称为introspection的过程)

  1. hashCode()是一个整数值,它为当前实例提供了几乎唯一的值。

–如果两个不同实例的哈希码相等,则它们可以相等; 为了确定完全相等,必须对属性(可能还有方法)进行详细比较;

–如果哈希码不相等,则实例也不相等。

–因此,哈希码可以加快相等性测试的速度。

–哈希码还可以用于创建HashMap(映射是使用哈希码加速查找的关联数组或字典)和HashSet(集合是对象的集合;程序员可以测试实例是否是否在集合中;使用哈希码来加快测试速度)

  1. notify() , notifyAll() , wait() , wait(long timeout)和wait(long timeout,int nanos)在单独线程上执行的协作实例之间进行通信。
  2. toString()生成实例的可打印版本。

总结

我们已经谈到了Java风格的面向对象编程的一些重要方面。 在以后的文章中将涉及六个重要的相关主题:

  • 命名空间和包。
  • 在子类中重写方法——例如,String 类有自己特定的 hashCode ()方法,该方法将其意义识别为字符数组; 这是通过重写从 Object 继承的 hashCode ()方法来实现的
  • 接口,允许描述必须由实现该接口的类提供的行为; 当只特定行为感兴趣时,可以通过该接口引用实现给定接口的类。
  • 原语或类的数组以及类的集合(例如列表,映射和集合)
  • 方法的重载-具有相同名称和相似行为的几种方法具有不同的参数。
  • 使用Java发行版随附的库。

接下来您想阅读什么吗? 让我们在评论中知道并继续关注!

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 继承
  • 强类型和静态类型
  • 基本类型、类和对象
  • Object 类
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档