zoukankan      html  css  js  c++  java
  • 3.3类与对象的语法细则

    用类定义对象——类的4大要素

    – 方法名
    – 形式参数列表
    – 方法体
    – 返回值类型
    1 类的定义 Java语法:定义类
    2 [public]class 类名 {
    3     [访问权限]数据类型 字段名[=初始值];
    4     ……
    5     [访问权限]返回值类型 方法名( 形式参数列表 ) {
    6 方法体
    7     }
    8 ……
    9 }
    方法名
    A) Java语言规定构造方法名与类名必须相同
    B) Java语言规定构造方法没有返回值,但不用void声明
    C) Java语言规定构造方法可以重载
    D) Java语言规定构造方法只能通过new自动调用
     
    this关键字
    类的下属成员有两种,分别是字段(存储数据)和方法(处理数据的算法)。某些特殊的类可能只包含一种成员,比如只包含字段,或只包含方法。
    类成员的访问权限有4种,分别是公有权限(public)、保护权限(protected)、私有权限(private)或默认权限(未指定访问权限)。
    例3-8 一个钟表类Clock的Java示意代码(Clock.java)
     1 import java.util.Scanner; // 导入外部程序Scanner
     2 
     3 public class Clock { // 定义钟表类Clock
     4 // 将字段设为private权限,即私有成员
     5     private int hour; // 字段hour:保存小时数
     6     private int minute; // 字段minute:保存分钟数
     7     private int second; // 字段second:保存秒数
     8 // 将方法设为public权限,即公有成员
     9 
    10     public void set() { // 不带参数的方法set():从键盘输入时间
    11         Scanner sc = new Scanner(System.in); // 创建键盘扫描器对象sc
    12         hour = sc.nextInt();
    13         minute = sc.nextInt();
    14         second = sc.nextInt();
    15     }
    16 
    17     public void set(int h, int m, int s) { // 带参数的方法set():用参数设定时间
    18         hour = h; minute = m; second = s; // 将参数分别赋值给对应的数据成员
    19     }
    20 
    21     public void show( ) { // 方法show:显示时间
    22         System.out.println( hour +”:” +minute +”:” +second ); // 显示格式:时:分:秒
    23         }
    24     }

    类的定义:

    字段成员的语法细则

    • 字段初始化
    private int hour = 0; // 将钟表的时间初始化为0:0:0
    private int minute = 0;
    private int second = 0;
    • 空值
    • 只读字段final
    private final int second = 0; // 将字段second定义成只读字段

    – 方法成员的语法细则

    • 方法的4大要素
    – 方法名--以小写字母开头
    – 形式参数列表--接受输入参数所需的变量,这些变量称为形式变量(形参)
    – 方法体--定义专供本方法使用的变量(局部变量;返回用return)
    – 返回值类型--无返回类型要定义为void
    • 方法签名:返回值类型 方法名(形式参数列表形参1,形参2,形参3)--定义方法的接口
     
    • 重载方法:相同的方法名
    public void set( ) { // 不带参数的方法set():从键盘输入时间
    Scanner sc = new Scanner( System.in );
    hour = sc.nextInt(); minute = sc.nextInt(); second = sc.nextInt();
    }
    public void set(int h, int m, int s) { // 带参数的方法set():用参数设定时间
    hour = h; minute = m; second = s;
    }
    两个存在时,调用同名的重载方法调用根据调用语句实参的个数和类型,来自动调用形参匹配的那个方法 

    – 类成员访问权限的语法细则

    • 公有权限public
    • 私有权限private
    • 保护权限protected
    • 默认权限(未指定访问权限)
     

    对象的定义与访问

    – 定义对象

    • 运算符new --来为对象分配内存
    • 引用及引用变量 --指向对象所分配内存的首地址
    Clock obj1; // 预先定义一个Clock类型的引用变量obj1// 此时obj1的引用值为null,即还未引用任何对象
    obj1 = new Clock( );
    上述两条语句可简写为一条语句:
    Clock obj1 = new Clock( );  //obj1是对象名
    • 请注意:“=”两边的类型应当一致

    – 访问对象

    • 成员运算符“.”
    – 对象名.字段名
    – 对象名.方法名(实参列表)
     
    •访问钟表对象的公有成员
    Clock obj1 = new Clock( ); // 创建一个钟表对象obj1
    obj1.set( ); // 调用对象obj1的公有方法set(),输入时分秒数据
    obj1.show( ); // 调用对象obj1的公有方法show(),显示其时间
     
    •可以用钟表类Clock定义(生产)多个钟表对象
    Clock obj2 = new Clock( ); // 创建第二个钟表对象obj2
    obj2.set( 8, 30, 15 ); // 调用对象obj2的公有方法set(),设置时间8:30:15
    obj2.show( ); // 调用对象obj2的公有方法show(),显示其时间
     
    •一个对象可以被多次引用
    Clock obj ; // 再定义一个Clock类的引用变量obj
    obj = obj1; // 赋值后,obj与obj1引用同一个对象,该对象被引用了2次
    obj.set( 12, 0, 0); // 通过引用变量obj操作钟表对象,将其时间设为12:0:0
    obj.show( ); // 显示对象的时间,显示结果应为:12:0:0
    obj1.show( ); // 显示obj1所引用对象的时间,显示结果也为:12:0:0
     

    • 引用数据类型

    基本数据类型(primitive data type)

    byte、short、int、long、float、double、char、boolean
    – Java语言中,使用基本数据类型定义变量,定义时直接为变量分配内存单元
    – 后续程序将通过变量名访问变量的内存单元
     

    引用数据类型(reference data type)

    类型、数组类型、接口类型、枚举类型等
    – 先定义引用数据类型的引用变量
    – 再用运算符new创建引用数据类型的对象,并
    将所返回的对象引用保存到引用变量中
    – 后续程序通过引用变量访问对象及其下属成员
     

    – 变量及对象的内存分配

    变量
    int x;
    double y;
    Clock obj1;
    以上都是局部变量:只能在栈内存分配内存

     

    引用数据类型

    – 变量及对象的内存分配
    对象
    obj1 = new Clock( ); --创建对象一当前被引用一次,计数1
    Clock obj2 = new Clock( );--创建对象二
     
     
    Clock obj;
    obj = obj1;--obj引用obj1 对象一引用次数为2
    obj = obj2;;--obj引用obj2 对象二引用次数为2
    obj = null;--刚才引用对象二,现在不引用 对象二将为1
    obj2 = null;--obj2引用对象不引用任何对象被 引用次数为0(– Java语言中的垃圾回收(garbage collection)机制)

    三种不同的变量

    字段:定义在类中的变量成员,用于保存属性数据。字段相当于是类中的全局变量,可以被类中的所有方法成员访问
    局部变量:类中方法成员在方法体中定义的变量,仅能在所定义的方法体或复合语句中访问
    形式参数(形参):类中方法成员在头部小括号里面定义的变量,用于接收原始数据。形参仅能在所定义的方法体中访问
    例3-10 一个为钟表设置整点时间的Java示例代码(ClockTest.java)
     1 import java.util.Scanner; // 导入外部程序Scanner
     2 
     3 public class ClockTest { // 主类
     4     public static void main(String[] args) { // 主方法
     5         int hour; // 局部变量:普通变量,未初始化
     6         Clock c1; // 局部变量:引用变量,未初始化
     7         hour = 12; c1 = new Clock(); // 为局部变量赋值
     8         c1.set(8, 30, 15); // 设置钟表对象c1的时间
     9         c1.show(); // 显示结果:8:30:15
    10             
    11         Clock c2; // 再定义一个局部引用变量c2 
    12         c2 = setHour( c1, hour ); // 调用setHour()将c1设为整点,并将返回值赋值给c2
    13         c2.show( ); // 显示c2的时间,结果应为:12:0:0 
    14         c1.show( ); // 显示c1的时间,结果也为:12:0:0
    15     }
    16 
    17     private static Clock setHour(Clock rc, int h) { // 将钟表时间设为整点的方法
    18         rc.set(h, 0, 0); // 设置rc的时间,小时数为接收的参数h,分钟和秒数设为0
    19         return rc;
    20     }
    21 }
    •传递基本数据类型数据时直接传递数值,即值传递
    •传递引用数据类型的对象时所传递的是对象引用(不是对象本身),这被称为是引用传递。--形参rc传递的是c1这个实参
     
     
     

    类与对象的编译原理

    类代码的编译

    public void set( int h, int m, int s ) {
        hour = h;
        minute = m;
        second = s; 
    }
    public void set( Clock this, int h, int m, int s ) {
        this.hour = h;
        this.minute = m;
        this.second = s; 
    }
    1 public void show( ) {
    2     System.out.println(
    3         hour +”:” +minute +”:” +second ); 
    4 }        
    1 public void show( Clock this )
    2     System.out.println(
    3         this.hour +”:” +this.minute +”:” +this.second ); 
    4 }    

    调用对象方法成员语句的编译

    Clock obj1 = new Clock( ); // 创建钟表对象obj1
    obj1.set( 8, 0, 0 ); // 将obj1的时间设为8:0:0
    obj1.show( ); // 显示obj1的时间,显示结果:8:0:0
     
    set( obj1, 8, 0, 0 );--调用set方法,按照顺序 实参obj1传值到set方法形参this
            void set(Clock this, int h, int m, int s) { … } 形参this所引用的是当前调用方法的对象obj1.set( 8, 0, 0 )——this=obj1;h=8;m=0;s=0
          this.hour = h; this.minute = m; this.second = s;
    show( obj1 );

    同类的多个对象在内存中共用一份方法代码

    Clock obj1 = new Clock( ); // 创建钟表对象obj1
    Clock obj2 = new Clock( ); // 创建钟表对象obj2 
    obj1.set( 8, 0, 0 );
    obj2.set( 9, 30, 15 );
    set( obj1, 8, 0, 0 );
    set( obj2, 9, 30, 15 );
    void set(Clock this, int h, int m, int s) { … }
     
    形参this是隐含的,在方法体中访访问其他类成员也不需要添加this引用,这些都由编译器在编译时自动添加
    – 程序员可以在访问类成员时显式添加“this.”,也可以通过this获取当前对象的引用,或把this作为实参将当前对象的引用继续传递给其他方法
    – 程序员还可以利用this来区分与形参或局部变量重名的字段
    public void set( int hour, int minute, int s ) {//传入形参hour、minute、s
      this.hour = hour; // “this.hour”指代的是字段hour
      this.minute = minute; // “this.minute”指代的是字段minute
      second = s; // 形参s与字段second不重名,可以不用this
    }
     

    类的构造方法 

    – 构造方法(constructor)是类中一种特殊的方法
    • 构造方法的名字必须与类名相同
    • 构造方法通过形参传递初始值,实现对新建对象字段成员的初始化
    • 构造方法可以重载,即定义多个同名的构造方法,这样可以提供多种形式的初始化方法
    • 构造方法没有返回值,定义时不能写返回值类型,写void也不行
    • 构造方法通常是类外调用,其访问权限不能设为private
    如果没有定义构造方法,编译器会给定空的构造方法:默认构造方法,格式为 类名() { } // 默认构造方法
     

    初始化对象

    public Clock( int p1, int p2, int p3 ) { // 带形参的构造方法
      hour = p1; minute = p2; second = p3;
    }
    public Clock( ) { // 不带形参的构造方法
      this( 0, 0, 0 ); // 调用本类重载的带形参构造方法(须为第一条语句)
      // hour = 0; minute = 0; second = 0; // 或直接赋值
    }
    Clock obj1 = new Clock( 8, 30, 15 ); // 给了实参,将调用带形参的构造方法
    Clock obj2 = new Clock( ); // 未给实参,将调用不带形参的构造方法
     
    Clock obj = obj1; // 未实际创建对象,不会调用构造方法
     调用方法遵守三条原则①构造方法是在使用类创造对象时,由系统自动调用的,理解为由运算符new调用的。程序员不能直接调用构造方法
    ②使用类创建对象,每创建个对象 就会调用一次类的构造方法,创建多少个对象就会调用多少次构造方法
    ③定义引用对象时不会调用对象,因此也不会调用构造方法
     

    – 拷贝构造方法

    用一个已经存在的对象来初始化当前正在创建的新对象

    public Clock( Clock oldObj ) {
      hour = oldObj.hour;
      minute = oldObj.minute;
      second = oldObj.second;
    }
    用一个已经存在的对象来初始化当前正在创建的新对象
    Clock obj1 = new Clock( 8, 30, 15 );
    Clock obj2 = new Clock( obj1 );  obj2显示的也时8:30:15

    显示对象的创建过程

    public Clock( ) { // 不带形参的构造方法
    hour = 0; minute = 0; second = 0;
    System.out.println( “Clock( ) called.” ); // 添加显示信息的语句
    }
    public Clock( int p1, int p2, int p3 ) { // 带形参的构造方法
    hour = p1; minute = p2; second = p3;
    System.out.println( “Clock(int p1, int p2, int p3) called.” ); // 添加显示信息的语句
    }
    public Clock( Clock oldObj ) { // 拷贝构造方法
    hour = oldObj.hour; minute = oldObj.minute; second = oldObj.second;
    System.out.println( “Clock( Clock oldObj ) called.” ); // 添加显示信息的语句
    }
    Clock obj1 = new Clock( ); // 未给实参:Clock( ) called.
    Clock obj2 = new Clock( 8, 30, 15 ); // 给3个int型实参:Clock(int p1, int p2, int p3) called.
    Clock obj3 = new Clock( obj2 ); // 给1个Clock型实参:Clock( Clock oldObj ) called.
  • 相关阅读:
    Eclipse中普通java项目转成Web项目
    spring MVC 转发与重定向(传参)
    spring MVC <mvc:annotation-driven>
    spring MVC 全局的异常处理
    spring MVC拦截器
    Spring Bean的作用域
    Spring 常用注解
    在普通类中获取Spring管理的bean
    Spring事务配置
    spring在普通类中获取session和request
  • 原文地址:https://www.cnblogs.com/lijingxiang/p/13954998.html
Copyright © 2011-2022 走看看