第九章 对象和类

引言

  • 面向对象编程实质上是一种开发可重用软件的技术

为对象定义类

  • 类为对象定义属性和行为
  • 对象代表现实世界中可以明确标识的一个实体
  • 一个对象的状态是由数据域及其当前值来表示的
  • 一个对象的行为是由方法定义的,调用对象的一个方法就是要求对象完成一个动作
  • 类是一个模版,蓝本或者合约,用来定义对象的数据域以及方法
  • 对象是类的实例
  • 可以从一个类中创建多个实例
  • 类提供一种构造方法,调用它可以创建一个新对象,构造方法本身是可以完成任何动作的,但是设计构造方法是为了完成初始化动作

定义类和创建对象

  • 类定义了对象,对象是从类创建的
  • 可以把两个类放在同一个文件中,但是文件中只能有一个类是公共类
  • 公共类必须与文件同名
  • 可以将两个类组合成一个
package chapter9;
//listing 9-2
public class AlternativeCircle {
	  /** Main method */
	  public static void main(String[] args) {
	    // Create a circle with radius 1
	    AlternativeCircle circle1 = new AlternativeCircle();
	    System.out.println("The area of the circle of radius "
	      + circle1.radius + " is " + circle1.getArea());
	  
	    // Create a circle with radius 25
	    AlternativeCircle circle2 = new AlternativeCircle(25);
	    System.out.println("The area of the circle of radius "
	      + circle2.radius + " is " + circle2.getArea());
	  
	    // Create a circle with radius 125
	    AlternativeCircle circle3 = new AlternativeCircle(125);
	    System.out.println("The area of the circle of radius "
	      + circle3.radius + " is " + circle3.getArea());
	  
	    // Modify circle radius
	    circle2.radius = 100;
	    System.out.println("The area of the circle of radius "
	      + circle2.radius + " is " + circle2.getArea());
	  }
	  
	  double radius; 
	 
	  /** Construct a circle with radius 1 */
	  AlternativeCircle() {
	    radius = 1;
	  }
	  
	  /** Construct a circle with a specified radius */
	  AlternativeCircle(double newRadius) {
	    radius = newRadius;
	  }
	  
	  /** Return the area of this circle */
	  double getArea() {
	    return radius * radius * Math.PI;
	  }
	  
	  /** Return the perimeter of this circle */
	  double getPerimeter() {
	    return 2 * radius * Math.PI;
	  }
	  
	  /** Set a new radius for this circle */
	  void setRadius(double newRadius) {
	    radius = newRadius;
	  }
	}



  • 定义TV类的程序:
package chapter9;
//listing 9-3
public class TV {
  int channel = 1; // Default channel is 1
  int volumeLevel = 1; // Default volume level is 1
  boolean on = false; // By default TV is off
  
  public TV() {
  }
  
  public void turnOn() {
    on = true;
  }
  
  public void turnOff() {
    on = false;
  }
  
  public void setChannel(int newChannel) {
    if (on && newChannel >= 1 && newChannel <= 120)
      channel = newChannel;
  }
  
  public void setVolume(int newVolumeLevel) {
    if (on && newVolumeLevel >= 1 && newVolumeLevel <= 7)
      volumeLevel = newVolumeLevel;
  }
  
  public void channelUp() {
    if (on && channel < 120)
      channel++;
  }
  
  public void channelDown() {
    if (on && channel > 1)
      channel--;
  }
  
  public void volumeUp() {
    if (on && volumeLevel < 7)
      volumeLevel++;
  }
  
  public void volumeDown() {
    if (on && volumeLevel > 1)
      volumeLevel--;
  }
}

  • 使用TV类创建两个对象的程序
package chapter9;
//listing 9-4
public class TestTV {  
  public static void main(String[] args) {
    TV tv1 = new TV();
    tv1.turnOn();
    tv1.setChannel(30);
    tv1.setVolume(3);
    
    TV tv2 = new TV();
    tv2.turnOn();
    tv2.channelUp();
    tv2.channelUp();
    tv2.volumeUp();
    
    System.out.println("tv1's channel is " + tv1.channel 
      + " and volume level is " + tv1.volumeLevel);
    System.out.println("tv2's channel is " + tv2.channel 
      + " and volume level is " + tv2.volumeLevel);
  }
}

使用构造方法构造对象

  • 使用new操作符调用构造方法创建对象
  • 构造方法是一种特殊的方法,有以下三个特殊之处:
  • 1,构造方法必须和所在类名字相同
  • 2,构造方法没有返回值类型,甚至连void都没有
  • 3,构造方法是在创建一个对象时有new操作符调用的,构造方法的作用是初始化对象
  • 构造方法和定义它的类名字完全相同
  • 构造方法也可以重载:可以有多个同名但是签名不同的构造方法
  • 构造方法是用来构造对象的的
  • 通常,类会提供一个没有参数的构造方法——>无参构造方法
  • 在一个类中,用户可能没有定义构造方法,在这种情况下,类中会隐式定义一个方法体为空的无参构造方法,这个构造方法称为默认构造方法,当且仅当类中没有明确定义任何构造方法时才会自动提供

通过引用变量访问对象

  • 对象的数据和方法可以运用点操作符( . )通过对象的引用变量进行访问
  • 新创建的对象在内存中被分配空间,它们可以通过引用变量来访问

引用变量和引用类型

  • 对象通过对象引用变量来访问的,该变量包含了对对象的引用
  • 类是一种引用类型,这意味着该类类型的变量都可以引用该类的一个实例
  • ClassName objectRefVar = new ClassName();
  • 对象引用变量只是存放了对该对象的引用
  • 在Java中,数组被看作对象,数组是用new操作符创建的,一个数组变量实际上是一个包含数组引用的变量

访问对象的数据和方法

引用数据域和null值

  • 数据域也可能是引用型的
  • 如果一个引用类型的数据域没有任何对象,那么这个数据域就有一个特殊的Java值null
  • 引用类型数据域的默认值是null,数值类型数据域的默认值是0,boolean类型的数据域的默认值是false,而char类型数据域的默认值是’\u000’
  • Java没有给方法中的局部变量赋默认值

基本类型变量和引用类型变量的区别

  • 每个变量都代表一个保存了存储值的内存位置
  • 对基本类型变量,对应内存所存储的值是基本类型值
  • 对引用类型变量,对象内存所存储的值是一个引用,是对象的存储地址
  • 引用赋值后,两个变量指向同一个对象

静态变量,常量和方法

  • 静态变量被类中的所有对象所共享
  • 静态方法不能访问类中的实例成员(即实例数据域和方法)
  • 静态变量将变量值存储在一个公共的内存地址,因为是公共的地址,所以如果某一个对象修改了静态变量的值,那么同一个类的所有对象都会收到影响
  • 声明或定义方法:加static
  • 静态变量和方法可以在不创建对象的情况下访问
  • main方法也是静态方法
  • 静态方法不能调用实例方法或者访问实例数据域
    在这里插入图片描述

可见性修饰符

  • public:类,方法和数据域可以被任何其他的类访问
  • private:限定方法和数据域只能在自己的类中访问
  • 如果一个类中没有被定义公共类,那么它只能在同一个包内被访问
  • 如果定义类时没有声明包,就表示把它放在默认包中
  • 如果一个类没有被定义为公共类,那么它只能在同一个包内访问

数据域封装

  • 使用private修饰符将数据域声明为私有的
  • 私有数据域不能被对象从定义该私有域的类外访问
{
  /** The radius of the circle */
  private double radius = 1;

  /** The number of the objects created */
  private static int numberOfObjects = 0;

  /** Construct a circle with radius 1 */
  public CircleWithPrivateDataFields() {
    numberOfObjects++;
  }

  /** Construct a circle with a specified radius */
  public CircleWithPrivateDataFields(double newRadius) {
    radius = newRadius;
    numberOfObjects++;
  }

  /** Return radius */
  public double getRadius() {
    return radius;
  }

  /** Set a new radius */
  public void setRadius(double newRadius) {
    radius = (newRadius >= 0) ? newRadius : 0;
  }

  /** Return numberOfObjects */
  public static int getNumberOfObjects() {
    return numberOfObjects;
  }

  /** Return the area of this circle */
  public double getArea() {
    return radius * radius * Math.PI;
  }
}
package chapter9;
//listing 9-9
public class TestCircleWithPrivateDataFields {
  /** Main method */
  public static void main(String[] args) {
    // Create a Circle with radius 5.0
    CircleWithPrivateDataFields myCircle = 
      new CircleWithPrivateDataFields(5.0);
    System.out.println("The area of the circle of radius "
      + myCircle.getRadius() + " is " + myCircle.getArea());

    // Increase myCircle's radius by 10%
    myCircle.setRadius(myCircle.getRadius() * 1.1);
    System.out.println("The area of the circle of radius "
      + myCircle.getRadius() + " is " + myCircle.getArea());
  }
}

向方法传递对象参数

  • 给方法传递一个对象,是将对象的引用传递给方法

对象数组

  • Circle[] circleArray = new Circle[10];
  • 对象的数组实际上是引用变量的数组
  • 当使用new操作符创建对象数组后,这个数组中的每个元素都是默认值为null的引用变量

不可变对象和类

  • 可以定义不可变对象来产生不可变对象
  • 不可变对象的内容不能被改变
  • 要求:
  • 1,所以数据域都是私有的
  • 2,没有修改器方法
  • 3,没有返回一个指向可变数据域的引用的访问器方法

变量的作用域

  • 实例变量和静态变量的作用域是整个类
  • 类变量只能声明一次
  • 如果一个局部变量和一个类变量具有相同的名字,那么局部变量优先,而同名的类变量将被隐藏

this引用

  • 关键字this引用对象自身,它也可以在构造方法内部用于调用同一个类的其它构造方法
  • 关键字this是一个对象可以用来引用自身的原因名
  • 可以用this关键字引用对象的实例成员
  • this引用通常被省略
  • 然而,在引用被方法或者构造方法的参数所隐藏的数据域以及调用一个重载的构造方法时,this引用时必需的

使用this引用数据域

  • 数据域radius被设置成方法中的参数radius所隐蔽

使用this调用构造方法

  • 关键字this可以用于调用同一个类的另一个构造方法
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值