面向对象其他知识点
1. final关键字
final是最终修饰符,可以修饰类,成员方法,变量。
final修饰的类无法被继承。
final修饰的方法无法被重写。
final修饰的变量,无法被再次赋值,变为了长量。
如:int a =10; //则a无法被二次赋值。
final的注意事项:1. 引用类型的变量值为对象地址值,地址值不能被更改,但是地址内的内容可以修改。
如: final Person p =new Person(); p不能为别的对象,但是p对象的name或age可更改。
2.修饰成员变量,需要在创建对象前赋值,否则报错。(当没有显式赋值时,多个构造方法均需为其赋值)
2. static关键字
static是静态修饰符,一般修饰成员。被static修饰的成员属于类,不属于单个这个类的某个对象。被static修饰的成员可以通过类名直接访问,也可以通过某个对象访问到属于类的静态成员,多个对象共享使用同一个静态成员。
格式:
类名.静态成员变量名
类名.静态成员方法名(参数)
对象名.静态成员变量名 ------不建议,出现警告
对象名.静态成员方法名(参数) ------不建议,出现警告
static注意事项
静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。
同一个类中,静态成员只能访问静态成员
main方法为静态方法仅仅为程序入口,不属于任何一个对象,所以可以定义在任意类中。
3.static与final连用定义静态常量
通常使用public static final来修饰某个类中的静态常量。此时标识符用全部大写,多个单词使用下划线连接。
格式: 类名.静态成员变量名
如:
定义包含静态成员的的类。
public classCompany{
public static final String COMPANY_NAME= “顺风通不通快递公司”;
public static void method(){
System.out.println(“一个静态方法”);
}
}
使用类的静态成员不需要创建对象,直接使用类名即可。
System.out.println(Company.COMPANY_NAME); //打印顺风通不通快递公司
Company.method(); //调用一个静态方法
接口中的每个成员变量都默认使用public static final修饰,所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
4.匿名对象
匿名对象指只有创建对象的语句,创建了对象,但是却没有赋值给某个变量。
匿名对象在没有指定其索引时,只能使用一次。
匿名对象的使用可以在任意位置:成员变量、方法参数、方法返回值等
如:
已经存在的类:
public class Person{
public void eat(){
System.out.println();
}
}
创建匿名对象直接使用,没有变量名。
new Person().eat() //eat方法被一个没有名字的Person对象调用了。
5. 内部类
内部类即在类中定义另外一个类,是一个相对概念。
内部类分为成员内部类与局部内部类。定义时是一个正常定义类的过程,同样包含各种修饰符、继承与实现关系等。
内部类可以直接访问外部类的所有成员。
外部类编译后会出现两个class文件。
5.1成员内部类
l 定义在成员位置的内部类
l 定义格式
public class Outer{
class Inner(){
//其他代码
}
}
l 访问格式:
Outer.Inner x = new Outer().new Inner();
5.2 局部内部类
l 定义在局部位置的内部类
l 定义格式
public class Outer{
public void method{
class Inner{
//其他代码
}
}
}
l 访问格式:
只能在外部类的方法中创建对象并访问。
6.内部类的实际使用——匿名内部类
a) 匿名内部类概念
内部类是为了应对更为复杂的类间关系。我们在完成计算机语言相对底层的位置才会涉及,日常业务中很难遇到,这里不做赘述。
最常用到的内部类就是匿名内部类,是局部内部类的一种。
匿名内部类有两个步骤:
l 临时定义一个类型的子类
l 定义后即刻创建刚刚定义的这个类的对象
b) 匿名内部类目的与格式
目的:匿名内部类是创建某个类型子类对象的快捷方式。
格式:
将定义子类与创建子类对象两个步骤由一个格式一次完成,多使用匿名对象的方式。虽然是两个步骤,但是两个步骤是连在一起的、即时的。
匿名内部类如果不定义变量引用,则也是匿名对象。格式如下:
new 父类(){
//重写需要重写的方法
};
例如:
已经存在的父类:
public abstract class Person{
publicabstract void eat();
}
定义并创建该父类的子类对象,并用多态的方式赋值给父类引用变量
Person p = new Person(){
publicvoid eat() {
System.out.println(“我吃了”);
}
};
7. 包
7.1包的概念与格式
a) 包的概念
分包管理是组织软件项目结构的基本方式。我们将同类功能放到一个包中,方便管理。并且日常项目的分工也是以包作为边界。
包在文件系统中是以文件夹的形式存在的。类中定义的包必须与实际class文件所在的文件夹情况相统一,即定义包时类在a包下,则生成的.class文件必须在a文件夹下,否则找不到类。
b) 包的定义格式
使用公司域名反写,多级包全部小写,用”.”连接
如:黑马程序员网址baidu.com那么域名反写就为com.baidu
类中的定义格式: package 包名;
7.2 包的访问
(前提:包的访问与访问权限密切相关,这里以一般情况来说,即类用public修饰的情况。)
在访问类时,为了能够找到该类,使用类时,应该使用包含 包 的类全名。
当被使用的类与使用的类在同一个文件夹下,或者被使用的类是java.lang包下时,我们通常可以省略掉类的包,直接使用类型,避免使用类全名。
当被使用的类与使用的类不在同一个文件夹下时,被使用者必须用public修饰才可被其他包下的类访问,我们可以通过导包的方式使用该类,避免使用类全名。
当多个文件夹下有相同的类名时,只能有一个导包使用,其他必须仍然书写全名。
导包格式:
package后,class前,使用import包名. 包名.类名;
7.3 访问权限
在Java中提供了四种访问权限,使用不同的访问权限时,被修饰的内容会有不同的访问权限,以下表来说明不同权限的访问能力:
| public | protected | default | private |
同一类中 | √ | √ | √ | √ |
同一包中(子类与无关类) | √ | √ | √ |
|
不同包的子类 | √ | √ |
|
|
不同包中的无关类 | √ |
|
|
|
所以,在日常开发过程中,如果允许其他包的类访问使用public,如果仅允许其他包的子类访问使用protected,仅本包内的类访问使用默认,仅能本类中访问使用private。
7.4 项目分层(分包)
一个项目随着功能的增加、继承树的扩展会出现众多的Java类。这时,不仅需要将一个类中的整体功能抽取出成为独立方法,还需要将功能边界即功能所有者界定,而这就是定义类与包的过程。在定义好不同的类之后,再将相似功能的类放到同一个包中进行统一管理。
8. 代码块
8.1 局部代码块
普通代码块就是直接定义在方法或语句中,以”{}”划定的代码区域,此时只需要关注作用域的不同即可,方法和类都是以代码块的方式划定边界的,如:
class Demo{
publicstatic void main(String[] args) {
{
intx = 1;
System.out.println("普通代码块" + x);
}
int x = 99;
System.out.println("代码块之外" + x);
}
}
结果:
普通代码块1
代码块之外99
8.2 构造代码块
直接定义在类中成员位置的代码块,优先于构造方法执行,构造代码块用于执行所有对象均需要的初始化动作,每创建一个对象均会执行一次构造代码块。
public class Person {
privateString name;
privateint age;
static{
System.out.println("静态代码块执行了");
}
{
System.out.println("构造代码块执行了");
}
Person(){
System.out.println("Person无参数的构造函数执行");
}
Person(intage){
this.age = age;
System.out.println("Person(age)参数的构造函数执行");
}
}
class PersonDemo{
publicstatic void main(String[] args) {
Person p = new Person();
Person p1 = new Person(23);
}
}
8.3静态代码块
静态代码块是定义在成员位置,使用static修饰的代码块。
优先于主方法执行,优先于构造代码块执行,当以任意形式第一次使用到该类时执行。
不管创建多少对象,静态代码块只执行一次。
可用于给静态变量赋值,用来给类进行初始化。
public class Person {
privateString name;
privateint age;
static{
System.out.println("静态代码块执行了");
}
}