Java面向对象(一)——类和类的成员
面向对象是相对于面向过程而言的。面向过程强调的是功能、行为,以函数为最小单位,考虑怎么做。而面向对象是将功能封装进对象,通过具体的对象调用方法,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。可见,面向对象是基于面向过程的。 本文基于atguigu的Java系列课程总结整理面向对象中的基础——类和类的成员。
1.类和对象
类是对一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。例如人是一个类,而具体的实实在在的张三、李四就是这个类的实例,拥有该类的属性,并且能够调用该类中声明的方法。程序设计的核心就是类的设计,也就是类的成员的设计。
2.类的成员
类的成员包括:属性、方法、构造器、代码块、内部类。
类及其成员设计举例如下,开发中不一定每个成员都会进行声明,例如代码块和内部类在日常开发中用的较少。
class Person {
// 属性**************
String name;
int age;
boolean sex;
// 构造器************
public Person() {
}
public Person(String name, int age, boolean sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 方法**************
public void eat() {
System.out.println("人吃饭!");
}
public String getName() {
return name;
}
// 代码块*************
{
name = "张三";
age = 18;
}
// 内部类**************
class Pet {
String name;
float weight;
}
}
2.1 属性
2.1.1 变量的分类
如上图所示,变量按照声明的位置不同分为成员变量(属性)和局部变量,两者的区别如下表所示:
异同点 | 成员变量 | 局部变量 |
---|---|---|
声明的位置 | 直接声明在类中 | 方法形参或内部、代码块内、构造器内等 |
修饰符 | private、public、static、final等 | 不能用权限修饰符修饰,可以用final修饰 |
初始化值 | 有默认初始化值 | 没有默认初始化值,必须显式赋值 |
内存加载位置 | 堆空间或静态域内 | 栈空间 |
2.1.2 属性的默认初始化值
成员变量类型 | 默认初始化值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0或写为:’\u0000’(表现为空) |
boolean | false |
引用数据类型 | null |
2.1.3 属性的赋值
属性的赋值操作执行顺序:
①默认初始化---->②显式初始化/③代码块赋值---->④构造器初始化---->⑤调用方法进行赋值
其中②和③处于同一位置,哪个先声明,哪个就先进行赋值。
2.2 方法
2.2.1 方法的分类
无返回值 | 有返回值 | |
---|---|---|
无形参 | 权限修饰符 void 方法名(){ } | 权限修饰符 返回值的类型 方法名(){ } |
有形参 | 权限修饰符 void 方法名(形参列表){ } | 权限修饰符 返回值的类型 方法名(形参列表){ } |
2.2.2 方法的重载与重写
重载是指在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可(即同类同名不同参)。需要注意的是,方法是否构成重载不取决于方法权限修饰符、返回值类型、形参变量名、方法体,只取决于参数列表。
重写是建立在继承特性的基础上的,是指在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
重写要求:
- 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表 ;
- 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型 (父类返回值类型是void或基本数据类型时,子类重写方法返回值类型必须与父类相同;当父类返回值类型是A类时,子类返回值类型可为A类或A的子类);
- 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限 (private除外,不能重写父类中声明为private权限的方法 );
- 子类方法抛出的异常不能大于父类被重写方法的异常 ;
此外,需要注意,子类与父类中同名同参数的方法必须同时声明为非static的,才算重写,同时声明为 static的不是重写。
2.2.3 可变个数形参
实际开发中,我们可能在定义方法时并不知道调用时传入的实参个数,这时我们可以使用可变个数形参的声明方式:
方式一:采用数组形参来定义方法,传入多个同一类型变量
public void test(int a ,String[] books){}
方式二:采用可变个数形参来定义方法,传入多个同一类型变量
public void test(int a ,String…books){}
需要注意的是,可变个数形参的方法与同名的方法之间构成重载,在方法调用时优先调用固定形参方法;可变形参需要声明在形参列表的最后,且最多只能声明一个。
2.2.4 方法的值传递机制
值传递是指将实际参数值的副本 (复制品)传入方法内,而参数本身不受影响。形参是基本数据类型时,将实参基本数据类型变量的“数据值”传递给形参 ;形参是引用数据类型时,将实参引用数据类型变量的“地址值”传递给形参。
2.3 构造器
构造器的作用时创建对象以及给对象初始化。构造器具有如下三个特征:
- 具有与类相同的名称 ;
- 不声明返回值类型;
- 不能被static、final、synchronized、abstract、native修饰,不能有 return语句返回值。
在Java中,每个类都至少有一个构造器。有时我们看到一个类中并没有定义构造器,但实际上这个类还是有一个系统默认提供的构造器——隐式无参构造器,默认构造器地修饰符与所属类地修饰符一致。我们也可以自己显示地定义一个或多个构造器(多个构造器构成了重载),可以是无参的也可以是有参的。当我们显示定义了构造器时,系统将不再提供默认的构造器了。此外,父类的构造器不可被子类继承。
构造器都会默认的声明super关键字,调用父类的构造器,不显式的声明,则程序会自动的调用Object类的无参构造器。子类中所有的构造器默认都会访问父类中空参数的构造器,当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器。同时,只能”二选一”,且必须放在构造器的首行。
另外,抽象类虽然不能被实例化,但也是有构造器的,这是供子类继承时调用的。
当然我们在开发中为了提高效率,可以使用开发工具去自动创建构造器。例如在eclipse中可以在Source---->Generate Constructor 利用属性或父类去自动创建构造器。
2.4 代码块
代码块的作用是对Java类或对象进行初始化 ,代码块只能使用static关键字修饰(或不修饰)。那么,按照是否使用static修饰可以将代码块分为静态的和非静态的。
静态代码块随着类的加载而执行,且只执行一次,执行上要优先于非静态代码块。并且在静态代码块中不能够调用非静态的属性和方法,也就是说不能对非静态的属性进行初始化。
非静态的代码块随着对象的创建而执行,每创建一次对象就执行一次,并且优先于构造器执行。非静态代码块除了能调非静态的结构外,还能调用静态的结构。
2.5 内部类
内部类是定义在一个类内部的类, 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。
内部类的名字不能与包含它的外部类重名,编译后也会生成对应的.class字节码文件。与变量的分类类似,内部类按照声明的位置不同分为成员内部类和局部内部类。
2.5.1 成员内部类
一方面,成员内部类作为类的成员具有以下特点:
- 可以调用外部类的结构 ;
- 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;
- 与外部类不同,内部类还可以用private或protected修饰。
另一方面,成员内部类作为类具有以下特点:
- 可以在内部定义属性、方法、构造器等结构 ;
- 可以被final、abstract修饰 ;
2.5.2 局部内部类
局部内部类具有以下特点:
- 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类;
- 可以使用外部类的成员,包括私有的;
- 可以使用外部方法的局部变量,但是必须是final的;
- 和局部变量地位类似,不能使用public,protected,缺省,private ;
- 不能使用static修饰,因此也不能包含静态成员。
以上就是关于Java面向对象部分类和类的成员的总结,希望对大家能有所帮助,有不对的地方欢迎大家指出!