类和对象

本文深入探讨面向对象编程(OOP)的关键概念,包括类、对象、封装、继承、多态等,解析预定义类的使用,如Math和Date类,强调封装的重要性,以及静态域与静态方法的区别。同时,讲解了callbyvalue和callbyreference的区别,以及对象构造过程中的初始化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

1、类和对象

2、封装

3、预定义类

4、继承

5、静态域与静态方法

6、call by value 和call by reference

7、对象构造

a、初始化块

b、显式域初始化


1、类和对象

由类构造 (construct ) 对象的过程称为创建类的实例 (instance ) .

使用 OOP,—定要清楚对象的三个主要特性:
•对象的行为(behavior)—可以对对象施加哪些操作,或可以对对象施加哪些方法?
•对象的状态 (state)—当施加那些方法时,对象如何响应?
•对象标识(identity )—如何辨别具有相同行为与状态的不同对象?
 

类的最常见(符号也最好辨认)的关系有:
•依赖 (“ uses-a”)
•聚合(“ has-a”)
•继承(“ is-a”)

 

2、封装

封装 ( encapsulation , 有时称为数据隐藏)是与对象有关的一个重要概念。 从形式上看,封装不过是将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域,操作数据的过程称为方法。

关键在于绝对不能让类中的方法直接地访问其他类的实例域。 程序仅通过对象的方法与对象数据进行交互。封装给对象赋予了“ 黑盒” 特征, 这是提高重用性和可靠性的关键。

一个私有数据源

一个公有域访问器

一个公有域更改器    可以防止某些地方邪恶的更改了数据源,可以做一些更改前的检查。
 

3、预定义类

例如 Math,Date类(表示时间点)、localDate类(日历表示法)。

封装了方法而不用看到具体的实现形式。  localDate不再是通过构造器来,而是静态工厂方法来进行。

localDate.now();
LocalDate newYearsEve = LocalDate.of(1999, 12, 31);
int year = newYearsEve.getYearO; // 1999
int month = newYearsEve.getMonthValueO; // 12
int day = newYearsEve.getDayOfMonth(); // 31
LocalDate newYearsEve = newYearsEve.piusDays(1000);

注意:不要返回引用可变的对象的访问器方法。看下面的代码

class Employee
{
   private Date hireDay ;
   public Date getHireDay{
     return hireDay; // Bad
   }
}
localDate这个改变值的方法,但Date类有一个setTime方法,它可以改变引用的值,这样就破坏了封装。
Employee em =  new Employee()
Date d = em.getHireDay();
double tenYearsInMilliSeconds = 10 * 365.25 * 24 * 60 * 60 * 1000;
d.setTime(d.getTime()-(long)tenYearsInMilliSeconds));
此时d和em.getHireDay()是引用的是同一个对象,d.setTime()的方法改变了Employee的私有数据域。

如果需要返回一个可变对象的引用,首先对它进行克隆。对象clone是指存放在另一个位置上的对象的复本。
class Employee{
  .....
    public Date getHireDay(){
        return (Date)hireDay.clone();
    }

}


4、继承

可以通过扩展一个类来建立另外一个新的类。

5、静态域与静态方法

a、final修饰符大都应用于基本(primitive)类型域,或不可变(immutable)类的域(如果类中的每个方法都不会改变其对象,这种就是不可变的类,比如String类)

对于可变对象用final修饰容易造成读者的误解

Employee(){
   private final StringBuilder evaluations;
}
evaluations指向的这个变量不会被其他的对象所引用

但是这个可以改变:evaluations.append(localDate.new()+"ending");

b、static静态域

实例域和静态域   静态域属于类不属于对象
class employee(){

    private String uuid;//对于实例域,每一个实例有一个自己的拷贝

    private static String taskId;//每一个实例共同拥有同一个域

}

    b.1 静态常量

public class System
{
public static final PrintStream out = . . .;

}
在类中的静态常量设置为public也并没有什么不妥,因为已经防止了其他的方法改变他的情况
…

  b.2静态方法  

  静态方法是不能对对象进行操作的方法,如Math.pom(x,a)计算的是x的a次方、程序入口的mian方法、   同样的静态方法是对类的操作不是对对象的操作,上图中的 Employee中的    public static getTaskId(){ return taskId;}这个不能对id进行操作。  

6、call by value 和call by reference

java程序设计语言总是通过call by call,方法得到的是所有参数的拷贝。方法不会修改传递给它的任何参数。

a、参数中的基础数据类型是call by value,对象是call by reference

double percent = 10;
harry.raiseSalary(percent):
b、参数中的基础数据类型是对象,

public static void tri pi eSalary(Employee x) // works
{
   x.raiseSa1ary(200) ;
}

下面总结一下 Java 中方法参数的使用情况:
• 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型)。
• 一个方法可以改变一个对象参数的状态。
• 一个方法不能让对象参数引用一个新的对象。

 

 

7、对象构造

一、构建对象时域的初始化    构建对象,就是用new class()语句建立一个新的类的对象。在这种情况下,类中的域是按照如下顺序进行初始化的:赋予默认值-->(静态域、静态块)-->(实例域、实例块)-->构造器。

a、初始化块

前面已经讲过两种初始化数据域的方法:
•在构造器中设置值
•在声明中赋值
实际上,Java 还有第三种机制, 称为初始化块(initializationblock)。
 

class Employee
{
    private static int nextld;
    private int id;
    private String name;
    private double salary;
    // object initialization block
    {    
        id = nextld;
        nextld++;
    }
    public Employee(String name, double salary){
        this.name = name;
        this.salary = salary;
    }
}
    

java中域的初始化       这部分摘自 https://www.cnblogs.com/jerry007/archive/2013/01/18/java%E4%B8%AD%E5%9F%9F.html

初始化域即给域赋值有以下几种方式:1)、赋予默认赋值   2)、声明变量时同时赋值     3)、块赋值(实例块和静态块)  4)、构造器赋值

如果同时存在以上几种赋值方式,那么域的最终值会是哪个呢?这里就涉及到域的初始化顺序的问题,同时也是下面要讲到的问题。      我们把域的初始化分为两种情况, 一种是在建立对象即进行类的实例化时域的初始化;另一种是在不建立对象,只装载类的时候域的初始化。

一、构建对象时域的初始化    构建对象,就是用new class()语句建立一个新的类的对象。在这种情况下,类中的域是按照如下顺序进行初始化的:赋予默认值-->(静态域、静态块)-->(实例域、实例块)-->构造器。    下面我给解释一下,假设一个域即变量int a,当建立对象时,首先赋予它一个默认值,int类型的默认值为0;如果a为静态域并且在静态块中被赋值,那么就按照静态域和静态块在程序中出现的顺序先后执行;如果同时还在实例块中被赋值,则再执行实例块中的赋值语句(静态域不可能再是实例域);最后执行构造器中的赋值语句(如果在构造器中有被赋值的话)。如果变量a是实例域,则不会有静态域和在静态块中赋值(不能在静态块中给实例域赋值)的情况,其他同前所述。    总结:静态域是指静态域在声明时被赋值,静态块是指在静态块中被赋值,实例域和实例块同上。上面列出的四个步骤是先后执行的;括号中的两种方式是同等级的,按照在程序中的顺序执行,排在前面的先执行,排在后面的后执行。    

二、装载类时域的初始化    有两种情况是只装载类而不实例化类,一是用java classname执行程序时;二是用classname.statement调用类的静态域或静态方法时。  装载类时这个类并没有被实例化,也就不能形成对象,所以不能对实例域进行初始化。因此只有静态域、静态块才能被初始化执行,执行规则同构建对象时的规则。

 

b、显式域初始化

在执行构造器之前,先执行赋值操作。当一个类的所有构造器都希望把相同的值赋予某个特定的实例域时,这种方式特别有用。

class Employee
{
    private static int nextld;
    private int id = assignld();
    private static int assignld() {
        int r = nextld;
        nextld++;
        return r;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值