Java面向对象--属性和方法
面向对象是相对于面向过程而言的,是软件开发方法。面向对象把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统设计,更贴近事物的自然运行模式。本篇博客介绍Java面向对象的属性(field)和方法(Method)。
目录:
属性(field)/变量
语法格式
☃ 修饰符 数据型 类型 属性名 = 初始化值;☄ 修饰符
常用的权限修饰符有:private、缺省(default)、protected、public
其他修饰符:static(类变量/静态变量)、final (使用final关键字后变量不允许修改)
☄ 数据类型
基本数据类型(如int、Boolean)和引用数据类型
☄ 属性名
属于标识符,符合命名规则和规范即可
✔ 修饰符只能在成员变量中使用,局部变量使用修饰符编译不通过
例子:
class Person{
public int age = 10;
private String name = "张三";
}
访问权限说明
访问修饰符 | 同一个类 | 同包 | 不同包,子类 | 不同包,非子类 |
---|---|---|---|---|
private | √ | |||
缺省(default) | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
成员变量与局部变量
☃ 在方法体外,类体内声明的变量称为成员变量☃ 在方法体内部声明的变量称为局部变量
☀ 注意:二者在初始化值方面的异同
◐ 同:都有生命周期
◑ 异:局部变量除形参外,均需显式初始化
class Person{
int age;
public static void main(String args[]){
double weight;
System.out.println(age); //输出0
//System.out.pritnln(weight); 编译不通过,必须赋初始值
}
}
成员变量(属性)和局部变量的区别
成员变量 | 局部变量 | |
---|---|---|
声明的位置 | 直接声明在类中(方法体外) | 方法形参或内部、代码块内、构造器内等 |
修饰符 | private、public、protected、static、final等 | 不能用权限修饰符修饰,可以用final修饰,其权限与声明它的方法对应 |
初始化值 | 有默认初始化值 | 没有默认初始化值,必须显式赋值,方可使用 |
内存加载位置 | 堆空间 或 静态域内 | 栈空间 |
对象属性的默认初始化赋值
当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值。除了 基本数据类型之外的变量类型都是引用类型,包括数组。成员变量类型 | 初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | '0'或写为'\u0000'(表现为空) |
boolean | false |
引用类型 | null |
方法(method)
☃ 方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程。☃ 将功能封装为方法的目的是,可以实现代码重用,简化代码
☃ Java里的方法不能独立存在,所有的方法必须定义在类里
方法的声明格式
```java 修饰符 返回值类型 方法名 ( 参数类型 参 形参1, 参数 类型 参 形参2, …. ){ 方法体程序代码 return 返回值; } ```☄ 修饰符
常用的权限修饰符有:private、缺省(default)、protected、public
☄ 返回值类型
没有返回值:void
有返回值,声明出返回值的类型。与方法体中<return 返回值>搭配使用
☄ 方法名
属于标识符,命名时遵循标识符命名规则和规范,“见名知意”
☄ 形参列表
可以包含零个,一个或多个参数。多个参数时,中间用“, ”隔开
☄ 返回值
方法在执行完毕后返还给调用它的程序的数据,与返回值类型对应
例子:
class Student{
String name;
int age;
char sex;
//getMessage()方法
public String getMessage(String name,int age,char sex){
name = name;
age = age;
sex = sex;
String message = "姓名:" + name + "\t年龄:" + age + "\t性别:" + sex;
return message;
}
}
方法的分类
有无形参 | 无返回值 | 有返回值 |
---|---|---|
无形参 | void 方法名 ( ) {} | 返回值的类型 方法名 ( ) {} |
有形参 | void 方法名 (形参列表) {} | 返回值的类型 方法名(形参列表){} |
方法的调用
☃ 方法通过方法名被调用,且只有被调用才会执行☀ 注意:
➣ 方法被调用一次,就会执行一次
➣ 没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可
以不必使用return语句。如果使用,仅用来结束方法,return后面不能再写其他代码
➣ 定义方法时,方法的结果应该返回给调用者,交由调用者处理
➣ 方法中只能调用方法或属性,不可以在方法内部定义方法
方法的详细使用
方法的重载(overload)
重载的概念
☃ 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数
类型不同即可
重载的特点
☃ 与返回值类型、形参变量名、方法体都无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型不同)。调用时,根据方法参数列表的不同来区别调用哪个
例子:
数字求和
//两个整数求和
int add(int a,int b){
int result = a +b;
return result;
}
//三个整数求和
int add(int a, int b, int c){
int result = a + b + c;
return result;
}
//两个小数求和
double add(double a, double b){
double result = a + b;
return result;
}
☀ 使用重载方法,可以为编程带来方便
可变个数的形参
JavaSE 5.0中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参
//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a ,String[] array);
//调用时,传入的参数也要是数组如 t.test(1,new String[]{"Hello" ,"world"})
//JDK5.0:采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a ,String…array);
//调用时直接传入同类型的参数即可,如 t.test(1,"hello", "world");
//两种定义方式原则上是一样的,不能同时出现,但两种方式的调用有区别
☀ 注意:
声明格式:方法名(参数的类型名 ...参数名)
可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
可变个数形参的方法与同名的方法之间,彼此构成重载
可变参数方法的使用与方法参数部分使用数组是一致的
方法的参数部分有可变形参,需要放在形参声明的最后
在一个方法的形参位置,最多只能声明一个可变个数形参
方法参数的值传递机制
☃ 方法,必须由其所在类或对象调用才有意义。若方法含有参数:
☄形参:方法声明时的参数
☄方法调用时实际传给形参的参数值
参数传递方式
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值传入方法内,而参数本身不受影响
☃ 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
public class ValueTransferTest {
public static void main(String[] args) {
int m = 10;
int n = 20;
// int temp = m;
// m = n;
// n = temp;
// System.out.println("m:" + m + " n:" + n);
// 输出 m:20 n:10
ValueTransferTest test = new ValueTransferTest();
test.swap(m, n);
System.out.println("m:" + m + " n:" + n);
//输出m:10 n:20
/*
* 原因是前一种方式是直接对 实参的操作,赋值操作后改变了实参的值
* 后一种方式是对形参的操作,不会影响到实参的值
*/
}
/*
*
* @method:swap
* @param a
* @param b
* @return:void
* @Description: 交换两数的值
*/
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
}
☃ 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
public class ValueTransferTest {
public static void main(String[] args) {
/*
* 引用数据类型传值
*/
Data data = new Data();
data.m = 10;
data.n = 20;
System.out.println("交换前:data.m:" + data.m + " data.n:" + data.n);
// int temp = data.m;
// data.m = data.n;
// data.n = temp;
// System.out.println("交换后:data.m:" + data.m + " data.n:" + data.n);
//输出 交换后:data.m:20 data.n:10
test.swap(data.m, data.n);
System.out.println("交换后:data.m:" + data.m + " data.n:" + data.n);
//输出 交换后:data.m:10 data.n:20
data.swap(data.m, data.n);
System.out.println("交换后:data.m:" + data.m + " data.n:" + data.n);
//输出 交换后:data.m:10 data.n:20
test.swap(data);
System.out.println("交换后:data.m:" + data.m + " data.n:" + data.n);
//输出 交换后:data.m:20 data.n:10
}
/*
* @method:swap
* @param a
* @param b
* @return:void
* @Description: 交换两数的值
*/
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
//重载swap方法
public void swap(Data data) {
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
class Data{
int m;
int n;
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
}
☀ 由于引用类型传递的是“地址值”,所以实参赋值或传递引用类型变量时,两个变量(包括形参变量)实际上指向的是同一块堆空间实体对象,一方对该对象进行了操作,另一方调用的就是操作后的对象
递归(recursion)
☃ 递归方法:一个方法体内调用它自身
☃ 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执
行无须循环控制
☃ 递归一定要向已知方向递归(递归有限次结束),否则这种递归就变成了无穷递归,类似于死循环,会报堆溢出错误
例子:
1-100累加的和
public int sum(int num){
if(num == 1){
return 1;
}else{
return num + sum(num -1);
}
}
本博客与CSDN博客༺ཌ༈君☠纤༈ད༻同步发布