面向对象(一)

面向对象(一)

一、类和对象

类——是一个模板,描述一类对象的行为和状态
对象——是类的一个实例,有状态和行为

1.定义类(class)

(1) 语法:

  [修饰符] class 类名{
    零个到多个成员变量
    零个到多个构造器定义
    零个到多个方法
    (零个到多个内部类、枚举、接口)
    (零个到多个代码块)
  }

修饰符:public、final、abstract或者完全省略(default)
类名:合法的标识符(最好是一个或多个有意义的单词连缀而成,驼峰命名法)
成员变量:用于定义该类的实例所包含的状态数据
构造器:用于创建该类的实例,通过new关键字来调用构造器,从而返回该类的实例
方法:用于定义该类或该类的实例的行为特征或者功能实现

2. 定义成员变量(field)

(1) 语法:

[修饰符] 类型 成员变量名 [=默认值]

修饰符:可以省略(default)或public、protected、private、static、final,其中public、protected、private 三个最多只能出现一个,可以与static、final组合使用
类型:基本数据类型或引用数据类型
成员变量名:合法的标识符(最好是一个或多个有意义的单词连缀而成,驼峰命名法)
默认值:定义成员变量可以指定一个可选的默认值

3. 定义方法(method)

(1) 语法:

  [修饰符] 方法返回值类型 方法名(形参列表){
    零条到多条可执行性语句组成的方法体;
    return 返回值;
  }

修饰符:可以省略或public、protected、private、static、final、abstract,其中public、protected、private 三个最多只能出现一个;abstract和final最多只能出现其中之一,final可以与static组合,但abstract不能与static组合。
方法返回值类型:Java语言允许的任何数据类型,包括基本数据类型和引用 数据类型;如果生命了方法返回值类型,方法体内必须有一个有效的return语句,该语句返回一个变量或一个表达式,且返回的类型必须声明的类型匹配。若没有返回值,必须使用void来声明没有返回值。
方法名:合法的标识符(最好是一个或多个有意义的单词连缀而成,驼峰命名法),由于方法用于描述类或实例的行为特征或功能实现,建议方法 名以英文动词开头。
形参列表:用于定义该方法可以接受的参数,由零组到多组“参数类型 形参名”组合而成,多组参数之间以英文逗号(,)隔开。
返回值:方法结束后的结果,用于把结果返回给调用者。

4. 定义构造器(constructor)

(1) 语法:

  [修饰符] 构造器名(形参列表){
    零条到多条可执行性语句组成的构造器执行体
  }

修饰符:可以省略(default)或public、protected、private其中一个
构造器名:必须和类名相同
形参列表:用于定义该构造器可以接受的参数,由零组到多组“参数类型 形名”组合而成,多组参数之间以英文逗号(,)隔开

5. 对象的产生和使用

(1) 产生:
  创建对象的根本途径是构造器,通过new关键字来调用某个类的构造器即可创建这个类的对象。
Java提供了一个功能,如果没有为一个类定义构造器,系统会为该类提供一个默认构造器(无参构造)。一旦提供了构造器,系统将不再提供默认构造器。

(2) 使用:
① 访问对象的实例变量
② 调用对象的方法

6. 对象、引用和指针

  对象是多块内存组成,不同内存块分别存储了对象的不同成员变量、方法等。
  引用相当于C语言里的指针,但Java把指针封装起来,避免开发者进行繁琐的指针操作。

  Person p = new Person()
产生了两个东西:一个是p变量,一个是Person对象
变量存放在栈内存,对象存放在堆内存
栈内存中的变量p实际是一个引用,指向堆内存中的Person对象

6. this 关键字

this关键字总是指向调用该方法的对象。(指向本类)
代表当前对象的一个引用

(1) 根据this出现位置的不同,this作为对象的默认引用有两种情形:
  1.构造器中引用该构造器正在初始化的对象
  2.在方法中引用该方法的对象
(2) 缺省this情况
(3) 使用情况
• 普通方法中使用this。
  • 区分类成员属性和方法的形参.
  • 调用当前对象的其他方法(可以省略)
  • 位置:任意
• 构造方法中使用this。
  • 使用this来调用其它构造方法
  • 位置:必须是第一条语句
this不能用于static方法

二、方法

1 . 定义

完成特定功能的代码块,为了提高代码的复用性

2. 属性

  Java方法不能独立存在,必须属于一个类或对象,因此方法不像C语言的函数被独立执行,执行方法时必须使用类或对象来作为调用者,即所有方法都必须遵循“类.方法”或“对象.方法”的形式来调用。

3. 参数传递机制

(1) 形参与实参

① 形参:全称为“形式参数”是在定义方法名的时候使用的参数,目的是用来接收调用该方法时传递的参数。
② 实参:全称为”实际参数”是在调用时传递给方法的参数,即传递给被调用函数的值。

实参传给形参可看做拷贝,基本数据类型拷贝的就是值,所以改了对原来的也没有影响。而引用数据类型拷贝的是地址值,和实参一样指向同一块地址,所以改了值就发生了改变

(2) 形参与实参的关系
① 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
② 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。
③ 实参和形参在数量上,类型上、顺序上应严格一致,否则就会发生类型不匹配的错误。
④ 遵循参数传递机制

(3) 参数传递机制——值传递
在传值调用的机制中只能把实参传送给形参,而不能把形参的值反向地传送给实参。
因此在方法调用过程中,形参值发生改变,而实参中的值不会变化。 而在引用调用的机制当中是将实参引用的地址传递给了形参,所以任何 发生在形参上的改变实际上也发生在实参变量上。
将实际参数的副本(复制品)传入方法内,但参数本身不会受到任何影响。

(4) 基本数据类型与引用数据类型的参数传递机制区别
基本数据类型的值传递

引用数据类型的值传递

4. 形参个数可变的方法

  在JDK 1.5之后,Java允许定义形参个数可变的参数,从而允许方法指定数量不确定的形参。
  在定义方法时,在最后一个形参的类型后增加三点(…)(不是中文省略号),表明该形参可以接受多个参数值,多个参数值被当成数组传入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
public static void main(String[] args) {
dealArray();//
dealArray(1);//1
dealArray(1,2,3);//123

}

public static void dealArray(int... intArray) {//intArray是个数组
for (int i : intArray) {
System.out.print(i + "");
}
System.out.println();
}
}

5. 递归方法

一个递归算法必须有两个部分:
初始情况和递归部分。
  初始情况只处理可以直接解决而不需要再次递归调用的简单输入。
  递归部分包含对算法的一次或者多次递归调用

源自递归算法(一个方法体内调用它自身)

案例:
1.阶乘

2.计算

6. 方法重载

同一个类中,方法名相同,但形参列表不同(类型、个数)

三、构造器

1 . 作用 :给对象的属性进行初始化
2 . 触发时间:创建对象的时候调用
3 . 重载构造器:方法名相同,参数列表不同
4 . 无参构造与有参构造
  如果没有给出构造方法,系统将自动提供一个无参构造方法。
  如果给出了构造方法,系统将不再提供默认的无参构造方法。如果想使用无参构造方法,就必须自己给出。
最好给出无参构造方法

• 构造器是一种特殊的方法:
  • 构造器的方法名必须和类名一致!
  • 构造器虽然有返回值,但是不能定义返回类型(返回值的类型肯定是本类),不能在构造器里调用 return。
  • 通过new关键字调用!!
  • 如果我们没有定义构造器,则系统会自动定义一个无参的构造方法。如果已定义则编译器不会 添加无参数构造方法!
  • 与普通方法一样,构造方法也可以重载

四、成员变量和局部变量

1.成员变量

  (1) 类变量和实例变量统称为成员变量。其中类变量可以理解为类成员变量,它作为类本身的一个成员,与类本身共存亡;实例变量则可以理解为实例成员变量,它作为实例的一个成员与实例共存亡。
  ①.类变量从该类的准备阶段起开始存在,直到系统完全销毁这个类,类变量的作用域与这个类的生存范围相同。只要类存在,类就可以访问类变量(类.类变量)
  ②.实例变量则从该类的实例被创建起开始存在,直到系统完全销毁这个实例,实例变量的作用域与对应实例的生存范围相同。只要实例存在,实例就可以访问实例变量(实例.实例变量)
  实例也可以访问类变量。但是需要注意的是因为实例不拥有类变量,所以通过实例来访问类变量进行操作,实际上是对类变量进行操作,当有其他实例来访问类变量时,访问的类变量是被对象访问操作过的类变量。

  (2) 成员变量无需显示初始化,只要为一个类定义了类变量或实例变量,系统就会在这个类的准备阶段或创建该类的实例时进行默认初始化。

2.局部变量

局部变量根据定义形式的不同,又可以分为如下三种:
(1) 形参:在定义方法签名时定义的变量,形参的作用域在整个方法中都有效
(2) 方法局部变量:在方法体内定义的局部变量,它的作用域是从定义该变量的地方生效,到该方法结束时失效
(3) 代码块局部变量:这个局部变量的作用域从定义该变量的地方生效,到该代码结束时失效。

  java允许局部变量和成员变量同名,如果方法中局部变量和成员变量同名,局部变量就会覆盖成员变量,如果需要在这个方法中引用被覆盖成员变量,则可使用this(对于实例变量)或类名(对于类变量)作为调用者来限定访问成员变量。

3. 成员变量与局部变量的初始化在内存中的运行机制

成员变量:
当系统加载类或者创建类的实例时,此时系统便自动为成员变量分配空间,并在分配空间后自动为成员变量指定初始化值

局部变量:
局部变量必须经过显示初始化之后才能使用,系统不会为局部变量执行初始化。定义了局部变量以后,系统并没有给局部变量进行初始化,直到程序给这个局部变量赋给初值时,系统才会为这个局部变量分配内存空间,并将初始值保存到这块内存中。

局部变量与成员变量不同,它不属于任何类或者实例,因此总是保存在其所在的方法的栈内存中。另外,栈内存中的变量无需系统垃圾回收,往往随方法或代码块的运行结束而结束。因此局部变量的范围是从初始化该变量开始的,知道该方法或该代码块运行完成而结束,同时它占用的内存区通常较小。
链接:https://www.jianshu.com/p/62c82e886388

4. 变量使用的规则

(1) 成员变量的弊端
  定义成员变量时,成员变量将被放置在堆内存中,成员变量的作用域将扩大到类存在范围或者对象存在范围,这种范围的扩大有两个弊端:
  ①增大了变量的生存时间,这将导致更大的内存开销
  ②扩大了变量的作用域,这不利于提高程序的内聚性
(2) 以下情况使用成员变量
  ①如果需要定义的变量是用于描述某个类或某个对象的固有属性信息,例如人的身高、体重等信息,这种变量应该定义为成员变量。
如果类的所有实例都有这种固有属性信息的值完全相同,则定义为类变量;如果每个实例的固有属性信息的值不完全相同,则定义为实例变量。
  ②如果在某个类中需要一个变量来保存类或实例运行时的状态信息,则使用成员变量。
  ③如果某个信息需要在某个类中的多个方法之间进行共享,则使用成员变量。

文章作者: Hai
文章链接: http://yoursite.com/2019/07/13/面向对象(一)/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hai
打赏
  • 微信
  • 支付宝