[REPRINT] Java 101: Classes and objects in Java

http://www.javaworld.com/article/2979739/learn-java/java-101-classes-and-objects-in-java.html?page=3

class Book
{
   // ...

   static int count;
}

This example declares a count integer field that stores the number of Book objects created. The declaration begins with the static keyword to indicate that there is only one copy of this field in memory. Each Book object can access this copy, and no object has its own copy. For this reason, count is known as a class field.

The previous fields were not assigned values. When you don't explicitly initialize a field, it's implicitly initialized with all of its bits set to zero. You interpret this default value as false (for boolean), '\u0000' (for char), 0 (for int), 0L (for long), 0.0F (for float), 0.0 (for double), or null (for a reference type).

class Book
{
   // ...

   static void showCount()
   {
      System.out.println("count = " + count);
   }
}

This example declares a showCount() method that will output the value of the count field. The declaration begins with the static keyword to indicate that this method belongs to the class and cannot access individual object state; no objects need to be created. For this reason, showCount() is known as a class method.

Method overloading

Java lets you declare methods with the same name but with different parameter lists in the same class. This feature is known as method overloading. When the compiler encounters a method-call expression, it compares the called method's comma-separated list of arguments with each overloaded method's parameter list as it looks for the correct method to call.

Two same-named methods are overloaded when their parameter lists differ in number or order of parameters. Alternatively, two same-named methods are overloaded when at least one parameter differs in type. For example, consider the following four draw() methods, which draw a shape or string at the current or specified draw position:

void draw(Shape shape)
{
   // drawing code
}

void draw(Shape shape, double x, double y)
{
   // drawing code
}

void draw(String string)
{
   // drawing code
}

void draw(String string, double x, double y)
{
   // drawing code
}

When the compiler encounters draw("abc");, it will select the third method because it offers a matching parameter list. However, what will the compiler do when it encounters draw(null, 10, 20);? It will report a "reference to draw is ambiguous" error message because there are two methods from which to choose.

You cannot overload a method by changing only the return type. For example, you couldn't specify int add(int x, int y) and double add(int x, int y) because the compiler doesn't have enough information to distinguish between these methods when it encounters add(4, 5); in source code. The compiler would report a "redefinition" error.

Constructors: Initializing objects

As well as explicitly assigning values to fields, a class can declare one or more blocks of code for more extensive object initialization. Each code block is a constructor. Its declaration consists of a header followed by a brace-delimited body. The header consists of a class name (a constructor doesn't have its own name) followed by an optional parameter list:

className ( [parameterList] )
{
   // constructor body
}

The following example declares a constructor in the Book class. The constructor initializes a Book object's title and pubYear fields to the arguments that were passed to the constructor's _title and _pubYear parameters when the object was created. The constructor also increments the count class field:

class Book
{
   // ...

   Book(String _title, int _pubYear)
   {
      title = _title;
      pubYear = _pubYear;
      ++count;
   }

   // ...
}

The parameter names have leading underscores to prevent a problem with the assignments. For example, if you renamed _title to title and specified title = title;, you would have merely assigned the parameter's value to the parameter, which accomplishes nothing. However, you can avoid this problem by prefixing the field names with this.:

class Book
{
   // ...

   Book(String title, int pubYear)
   {
      this.title = title;
      this.pubYear = pubYear;
      ++count;
   }

   // ...

   void setTitle(String title)
   {
      this.title = title;
   }

   void setPubYear(int pubYear)
   {
      this.pubYear = pubYear;
   }

   // ...
}

A parameter (or local variable) name that's identical to an instance field name shadows (meaning hides or masks) the field. Keyword this represents the current object (actually, its reference). Prepending this. to the field name removes the shadowing by accessing the field name instead of the same-named parameter.

Although you can initialize fields such as title and pubYear through the assignments shown above, it's preferable to perform the assignments via setter methods such as setTitle() and setPubYear(), as demonstrated below:

class Book
{
   // ...

   Book(String title, int pubYear)
   {
      setTitle(title);
      setPubYear(pubYear);
      ++count;
   }

   // ...
}
Constructor calling

Classes can declare multiple constructors. For example, consider a Book constructor that accepts a title argument only and sets the publication year to -1 to indicate that the year of publication is unknown. This extra constructor along with the original constructor are shown below:

class Book
{
   // ...

   Book(String title)
   {
      setTitle(title);
      setPubYear(-1);
      ++count;
   }

   Book(String title, int pubYear)
   {
      setTitle(title);
      setPubYear(pubYear);
      ++count;
   }

   // ...
}

But there is a problem with this new constructor: it duplicates code setTitle(title); located in the existing constructor. Duplicate code adds unnecessary bulk to the class. Java provides a way to avoid this duplication by offering this() syntax for having one constructor call another:

class Book
{
   // ...

   Book(String title)
   {
      this(title, -1);

      // Do not include ++count; here because it already
      // executes in the second constructor and would 
      // execute here after this() returns. You would end
      // up with one extra book in the count.
   }

   Book(String title, int pubYear)
   {
      setTitle(title);
      setPubYear(pubYear);
      ++count;
   }

   // ...
}

The first constructor uses keyword this followed by a bracketed argument list to call the second constructor. The single parameter value is passed unchanged as the first argument, and -1 is passed as the second argument. When using this(), remember that it must be the first piece of code in a constructor; otherwise, the compiler reports an error.

Objects: Working with class instances

Once you have declared a class, you can create objects from it. An object is nothing more than a class instance. For example, now that the Book class has been declared, you can create one or more Book objects. Accomplish this task by specifying the new operator followed by a Book constructor, as follows:

Book book = new Book("A Tale of Two Cities", 1859);

new loads Book into memory and then calls its constructor with arguments "A Tale of Two Cities" and 1859. The object is initialized to these values. When the constructor returns from its execution, new returns a reference (some kind of pointer to an object) to the newly initialized Book object. This reference is then assigned to the book variable.

Constructor return type

If you were wondering why a constructor doesn't have a return type, the answer is that there is no way to return a constructor value. After all, the new operator is already returning a reference to the newly-created object.

After creating a Book object, you can call its getTitle() and getPubYear() methods to return the instance field values. Also, you can call setTitle() and setPubYear() to set new values. In either case, you use the member access operator (.) with the Book reference to accomplish this task:

System.out.println(book.getTitle()); // Output: A Tale of Two Cities
System.out.println(book.getPubYear()); // Output: 1859
book.setTitle("Moby Dick");
book.setPubYear(1851);
System.out.println(book.getTitle()); // Output: Moby Dick
System.out.println(book.getPubYear()); // Output: 1851
Messaging objects

Calling a method on an object is equivalent to sending a message to the object. The name of the method and its arguments are conceptualized as a message that is being sent to the object on which the method is called.

You don't have to create any Book objects to call class methods. Instead, you prepend the class name and member access operator to the class method's name when calling these methods:

Book.showCount(); // Output: count = 1

Finally, it's possible to get and set the values of Book's instance and class fields. Use an object reference to access an instance field and a class name to access a class field:

System.out.println(book.title); // Output: Moby Dick
System.out.println(Book.count); // Output: 1
book.pubYear = 2015;
System.out.println(book.pubYear); // Output: 2015

I previously mentioned that instance methods affect only the objects on which they are called; they don't affect other objects. The following example reinforces this truth by creating two Book objects and then accessing each object's title, which is subsequently output:

Book book1 = new Book("A Tale of Two Cities", 1859);
Book book2 = new Book("Moby Dick", 1851);
Book book3 = new Book("Unknown");
System.out.println(book1.getTitle()); // Output: A Tale of Two Cities
System.out.println(book2.getTitle()); // Output: Moby Dick
System.out.println(book3.getPubYear()); // Output: -1
Book.showCount(); // Output: count = 3
Information hiding and access levels

A class's body is composed of interface and implementation. The interface is that part of the class that's accessible to code located outside of the class. The implementation is that part of the class that exists to support the interface. Implementation should be hidden from external code so that it can be changed to meet evolving requirements.

Consider the Book class. Constructor and method headers form this class's interface. The code within the constructors and methods, and the various fields are part of the implementation. There is no need to access these fields because they can be read or written via the getter and setter methods.

However, because no precautions have been taken, it's possible to directly access these fields. Using the previous book reference variable, you could specify book.title and book.pubYear, and that would be okay with the Java compiler. To prevent access to these fields (or at least determine who can access them), you need to take advantage of access levels.

An access level is an indicator of who can access a field, method, or constructor. Java supports four access levels: private, public, protected, and package (the default). Java provides three keywords that correspond to the first three access levels:

  1. private: Only code in the same class as the member can access the member.
  2. public: Any code in any class in any package can access the member.
  3. protected: Any code in the same class or its subclasses can access the member.

If there is no keyword then package access is implied. Package access is similar to public access in that code outside of the class can access the member. However, unlike public access, the code must be located in a class that belongs to the same package (discussed later in the Java 101 series) as the class containing the member that is to be accessed.

You can prevent external code from accessing Book's title and pubYear fields so that any attempt to access these fields from beyond Book will result in a compiler error message. Accomplish this task by prepending private to their declarations, as demonstrated below:

转载于:https://www.cnblogs.com/yaos/p/7086976.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存工具 SimpleCache SimpleCache 是一个简单易用的java缓存工具,用来简化缓存代码的编写,让你摆脱单调乏味的重复工作!1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后端缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. 支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是一个用来操作Windows注册表的 Java 类库,你可以用来对注册表信息进行读写。 GIF动画制作工具 GiftedMotion GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端 JOpenID JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值