包括面向对象程序设计中的概念,面向对象编程,三大特性:封装、继承、多态,类与对象,方法定义、调用、重载和递归,空指针异常,(实例、静态)(变量、方法),静态代码块、实例语句块,this/this()、super、final关键字
【Java类与对象(14)】
1.面向对象程序设计中的概念
主要包括:对象、类、数据抽象、继承、动态绑定、数据封装、多态性、消息传递。
通过这些概念面向对象的思想得到了具体的体现。
概念 | 解释 |
---|---|
对象(Object) | 可以对其做事情的一些东西。一个对象有状态、行为和标识三种属性。 |
类(class) | 一个共享相同结构和行为的对象的集合。类(Class)定义了一件事物的抽象特点。通常来说,类定义了事物的属性和它可以做到的行为。举例来说,“狗”这个类会包含狗的一切基础特征,例如它的孕育、毛皮颜色和吠叫的能力。类可以为程序提供模版和结构。一个类的方法和属性被称为“成员”。 |
封装(encapsulation) | 第一层意思:将数据和操作捆绑在一起,创造出一个新的类型的过程。第二层意思:将接口与实现分离的过程。 |
继承 | 类之间的关系,在这种关系中,一个类共享了一个或多个其他类定义的结构和行为。继承描述了类之间的“是一种”关系。子类可以对基类的行为进行扩展、覆盖、重定义。 |
组合 | 既是类之间的关系也是对象之间的关系。在这种关系中一个对象或者类包含了其他的对象和类。组合描述了“有”关系。 |
多态 | 类型理论中的一个概念,一个名称可以表示很多不同类的对象,这些类和一个共同超类有关。因此,这个名称表示的任何对象可以以不同的方式响应一些共同的操作集合。 |
动态绑定 | 也称动态类型,指的是一个对象或者表达式的类型直到运行时才确定。通常由编译器插入特殊代码来实现。与之对立的是静态类型。 |
静态绑定 | 也称静态类型,指的是一个对象或者表达式的类型在编译时确定。 |
消息传递 | 指的是一个对象调用了另一个对象的方法(或者称为成员函数)。 |
方法 | 也称为成员函数,是指对象上的操作,作为类声明的一部分来定义。方法定义了可以对一个对象执行那些操作。 |
2.面向对象编程
面向对象编程—Object-Oriented Programming,OOP。
OOP=对象+类+继承+多态+消息,其中核心概念是类和对象。
本质就是:以类的方式组织代码,以对象的组织(封装)数据。
OO(object-oriented):
基于对象概念,以对象为中心,以类和继承为构造机制,来认识,理解,刻画客观世界和设计,构建相应的软件系统的一门方法;
本意模拟人类的思维方式,使开发,维护,修改更加容易。
OOA(object-oriented analysis):
强调的是在系统调查资料的基础上,针对OO方法所需要的素材进行的归类分析和整理,而不是对管理业务现状和方法的分析
其实就是进一步对oo进行细化,初步得出该oo的属性与方法(或者简单的理解:在得出的文档中对接口的粗略定义)
OOD(object-oriented design):
OO方法中一个中间过渡环节,其主要作用是对ooa分析的结果作进一步的规范化整理,以便能够被OOP直接接受
整理和定义oo的属性和方法
OOP(object-oriented programming):
把组件的实现和接口分开,并且让组件具有多态性----(抽象,继承,封装,多态)面向接口编程。
3.三大特性:封装,继承,多态
3.1 封装:
把客观的事物封装成抽象的类,并且类可以把自己的数据和方法只让 可信的类或者对象操作,对不可信的类进行信息的隐藏。
简单的说就是:封装使对象的设计者与对象的使用者分开,使用者只要知道对象可以做什么就可以了,不需要知道具体是怎么实现的。
提高类和系统的安全性。
通过封装,我们可以保护代码被破坏,提高数据安全性。
提高代码的复用性
(有些方法、类在很多地方都能多次反复使用)通过封装,带来的高内聚和低耦合,使用不同对象、不同模块之间能更好的协同
3.2 继承:
继承指的是建立一个新的派生类,从一个或多个先前定义的类中继承数据和函数,可以重新定义或加进新数据和函数,从而建立了类的层次或等级,继承原有的功能,增加自己新的功能,实现了拓展和复用。
在Java继承可以使用 extends 关键字来实现,其中Java规定了java.lang.Object 类作为所有的类直接或间接的父类(当类没有继承其他类时,java默认继承Object类,当类继承了其他类时,可以向上追溯,最终继承的类就是Object类)。java规定类只能继承一个类且继承是受权限修饰符影响的。
子类不会继承父类的构造方法,但是会调用(子类初始化前会先初始化父类)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表(这就是Java要设置一个默认的无参构造的缘故)
继承中的关键字:extends、super 、this、final
extends:
单一继承,可以让一个类继承一个父类
super:
我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this:
指向自己的引用。引用自身的属性和方法。
final:
当用final修饰类时,是把类定义为不能继承的,即最终类;
用于修饰方法时,该方法不能被子类重写;
用于修饰属性时,和static一起使用,表明为一个常量,各类的所有对象共用一个值
子类无法继承private修饰的属性和方法;
子类和父类在同一包下,可以继承default权限的属性方法;
子类可以对父类进行扩展,拥有自己的属性和方法;
子类可以重写父类的方法(前提是可以继承到这个方法);
3.3 多态
java程序分为编译阶段和运行阶段
分析:a2.move();
先来分析编译阶段:
对于编译器来说,编译器只知道的类型是Animal,所以编译器在检查语法的时候,会去Animal.class字节码文件中找move方法,找到了,绑定上move()方法,编译通过,静态绑定成功。编译阶段属于静态绑定。
再来分析运行阶段:
运行阶段的时候,实际上在堆内存中建的java对象是cat对象,所以move的时候,真正参与move的对象是一只猫,所以运行阶段会动态执行cat对象的move()方法。这个过程属于运行阶段绑定,运行阶段绑定属于动态绑定。
什么是多态 ? 多种形态 ,多种状态。
多态表示多种形态:
编译的时候一种形态。
运行的时候另一种形态。
多态性指的是:
同一操作作用与不同类的实例,将产生不同的执行结果,即不同类的对象收到相同的消息时,将得到不同的结果。
类的多态
其实就是一种继承关系。
向上转型
向上转型其实就是父类对子类的引用。这个特点其实就是设计原则中的里式替换原则的原理。子类至少是一个父类,所以父类出现的地方,其子类一定可以出现。
//狗继承与Animals ,所以可以向上转型,用Animals引用Dog类
//能引用是因为狗至少是一种动物,它有动物类所有属性和方法
Animals animals= new Dog();
向下转型
向下转型是讲父类转型位子类,这种转型通常会出现问题,在具体使用向下转型的时候需要使用显式类型转换。
在多态发生时,子类只能调用父类中的方法(编译时类型的方法),而子类自己独有的方法(运行时类型的方法)无法调用,如果强制调用的话就需要向下转型。
向下转型通常配合 instanceof关键字使用,用于判断一个实例对象是否属于某个类,判断一个类是否实现了某个接口。当我们使用向下转型时,可能会出现一些问题,所以在之前需要先判断一下。Instanceof
第一:instanceof可以在运行阶段动态判断引用指向的对象的类型。
第二:instanceof的语法:A instanceof B A是不是B类
第三:instanceof运算符的运算结果只能是:true/false
方法的多态:
重写(Override)(方法覆盖):
重写是子类对父类允许访问的方法进行重写, 返回类型可以不相同,但是必须是父类返回值的派生类。
子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。声明为 final 的方法不能被重写。声明为 static 的方法不能被重写,但是能够被再次声明。
子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
限制:构造方法不能被重写。
访问权限不能比父类中被重写的方法的访问权限更低。
父类的成员方法只能被它的子类重写,子类能够根据需要实现父类的方法重写方法抛出的异常范围不能大于父类。
异常也有继承关系,所以子类能抛出的异常不能高于父类。
参数列表必须完全相同。
重载(Overload):
重载是在一个类里面,方法名字相同,而参数不同。
返回类型可以相同也可以不同。
方法能够在同一个类中或者在一个子类中被重载。
被重载的方法必须改变参数列表(参数个数或类型不一样)。
被重载的方法可以改变返回类型。
被重载的方法可以改变访问修饰符。
被重载的方法可以声明新的或更广的检查异常。
无法以返回值类型作为重载函数的区分标准。
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现
重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载。
方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写。
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
4.类与对象
类与对象的关系:
类是一种抽象的数据类型,它是对某一类事物整体描述、定义,但是并不能代表某一个具体的事物;对象是抽象概念的具体实例。
创建与初始化对象:
对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。
创建对象需要以下三步:
声明:声明一个对象,包括对象名称和对象类型。
实例化:使用关键字 new 来创建一个对象。
初始化:使用 new 创建对象时,会调用构造方法初始化对象。
构造器:类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的。
特点:
必须和类的名字相同,必须没有返回类型,也不能写void。
每个类都有构造方法,如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。
构造方法的名称必须与类同名,一个类可以有多个构造方法。
一个类可以包含以下类型变量:
局部变量:
在方法、构造方法或者语句块中定义的变量被称为局部变量。
变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:
成员变量是定义在类中,方法体之外的变量。
这种变量在创建对象的时候实例化。
成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:
类变量也声明在类中,方法体之外,但必须声明为 static 类型。
一个类可以拥有多个方法,在上面的例子中:eat()、run()、sleep() 和 name() 都是 Dog 类的方法。
5.方法定义,调用,重载和递归
5.1 方法定义
将具有独立功能的代码块组织成为一个整体,使其成为具有特殊功能的代码集。
方法必须先创建才可以使用,该过程称为方法定义。
方法定义时,参数中的 数据类型 和 变量名 都不可以省略,缺少其中任意一个,程序将报错。多个参数之间用逗号进行分割。
不带参数的方法定义格式:
public static void 方法名(){
//方法体,根据实际需求编写的代码块
}
带参数的方法定义格式:
public static void 方法名(参数1,参数2,…){//参数的一般格式:数据类型 变量名
//方法体
}
方法定义的通用格式:
public static 返回值类型(参数){
//明确返回值类型,没有,就写void。明确参数的类型和数量。
方法体;
return 数据;
}注意:
public static 是修饰符。
返回值类型:
方法操作完毕之后,返回的数据的类型。如果方法操作完毕没有数据返回,返回值类型写void,而且方法体中一般不写return。
方法名:
调用方法时使用的标识。
参数:
由数据类型和变量名组成,多个参数之间用逗号隔开。
方法体:
完成功能的代码块。
return :
如果方法操作完毕有数据返回,用于把数据返回给调用者。
5.2 方法调用:
方法创建后并不是直接运行的,需要手动使用后才可执行,该过程称为方法调用。
方法调用要在main()方法中调用,因为这是程序的入口。
当方法调用出现以后,会进入到相应的方法中,程序从上到下开始执行。
方法调用时的参数的数量与类型,必须与方法 定义中的设置相匹配,否则程序报错。
不带参数的方法调用格式:方法名();
带参数的方法调用格式:方法名(参数);//参数为变量名或常量值,多个参数之间用逗号分割。
参数分类:形参:方法定义中的参数,等同于变量定义的格式:数据类型 变量名;
实参:方法调用中的参数,等同于直接使用变量或常量。
方法的参数传递:
对于基本数据类型的参数,形参的改变不影响实参的值。
对于引用类型的参数,形参的改变影响实参的值。
方法调用时:
void类型的方法,直接调用即可。
非void类型的方法,一般用变量接收调用。
数据类型 变量名 = 方法名(参数);
5.3 方法重载:
内容:
同一个类中定义的多个方法之间的关系,满足一定条件的多个方法相互构成重载。重载仅针对方法的定义而言,与方法的调用无关。重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关。不能够通过返回值来判定两个方法是否相互构成重载。在调用的时候,JVM会通过参数的不同来区分同名的方法。
条件:
多个方法在同一个类中,具有相同的方法名,参数不相同(数据类型不同或数量不同)。返回类型、修饰符可以相同,也可不同。要求同名的方法必须有不同的参数表,仅有返回类型不同是不足以区分两个重载的方法。
5.4 方法递归
内容:
方法自己调用自己,这就是方法递归。
递归必须要有结束条件,递归有时候会栈内存溢出错误。因为有可能递归的太深了,栈内存不够了,因为一直接在压栈。
在实际开发中,不建议轻易选择递归,能用for循环while循环代替的,尽量使用循环来做。因为循环的效率高,耗费的内存少。递归耗费的内存比较大,另外递归的使用不当,会导致jvm死掉。(但在极少数的情况下,不递归,这个程序没法实现)。
6.空指针异常
空指针异常(NullPointerException)意思是指java中的异常类。
当应用程序试图在需要对象的地方使用null时,抛出该异常。
7.(实例、静态)(变量、方法)
实例方法可以引用实例变量、实例方法:
如果在不同类中,则需要先实例化对象,通过对象进行引用,对象名.实例变量名,对象名.实例方法名( )。
如果在同一个类中,则直接引用即可;
静态方法、实例方法可以引用静态变量、静态方法;
如果在不同类中,则是通过 类名.静态变量名 和 类名.静态方法名( )的方式引用;
如果是在同一个类中,则可以省略类名;
静态方法中不能使用 this 和 super ,而实例方法可以。
静态变量被所有类实例对象所共享,在内存中只有一个副本,当且仅当在类初次加载时会被初始化。
实例变量是实例对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个实例对象拥有的副本互不影响。
8.静态代码块,实例语句块
静态代码块:
使用static关键字可以定义:静态代码块。
静态代码块的语法:
static{
java语句;
java语句;
}
执行:
静态代码块在类加载的时候进行,并且只执行一次,一个类中可以有多个静态代码块。
注意:
静态代码块在类加载的时候执行,并且在main方法之前。
静态代码块一般是按照自上而下的顺序来执行的。
初始化:
在类加载的时候进行初始化。
存储在方法区内存。
实例语句块:
实例语句块不是在类加载的时候进行。
实例语句块的语法:
{
java语句;
java语句;
}
执行:
只要是构造方法执行,必然在构造方法执行之前,自动执行”实例语句块”中的代码。
调用一次,执行一次。
即是先执行实例方法块,再执行构造方法中的代码。
9. this/this(),super,final关键字
this:
区分局部变量和成员变量;
指代对象本身
方法的调用必须通过对象才能进行
this()调用构造方法
this()只能在构造方法中出现
构造方法中若出现this(),则必须是第一条语句
this()的使用应避免递归问题,Java编译器拒绝递归构造
参数个数决定其调用的具体构造方法
super
在子类内部调用父类对象
基础语法:
在类的继承中,当子类继承了父类, 在构造子类的时候,一定要先帮助父类进行构造;
调用super()必须写在子类构造方法的第一行,以保证在执行任何动作前,对象已经完成了初始化,否则编译不通过。
每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
三种用法
- super.xxx;
xxx可以是类的属性。
例如super.name;即从子类中获取父类name属性的值
- super.xxx();
xxx()可以是类中的方法名。
super.xxx();的意义是直接访问父类中的xxx()方法并调用 - super();
此方法意义是直接调用父类的构造函数。
super(无参/有参)即调用父类中的某个构造方法,括号里的内容根据你所调用的某个构造函数的变化而改变
final
final修饰类中的属性或者变量
无论属性是基本类型还是引用类型,final所起的作用都是变量里面存放的“值”不能变。
final修饰类中的方法
作用:可以被继承,但继承后不能被重写。
final修饰类
作用:类不可以被继承。
final修饰局部变量
系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化。因此使用final修饰局部变量时,即可以在定义时指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋初值(仅一次)。
10.内部类
成员内部类
类比成员方法,不能拥有静态域但是可以访问外部类的静态域
说明:
成员内部类是定义在外部类的成员位置,并且没有static修饰。
可以直接访问外部类的所有成员,包含私有的。
可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
作用域和外部类的其他成员一样,为整个类体,在外部类的成员方法中创建成员内部类对象,再调用方法。
如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
内部类与外部类的关系:
成员内部类的创建需要依赖于外部类对象,成员方法必须通过对象调用,在没有外部类实例之前无法创建成员内部类对象,内部类与外部类相对独立,不是is a 的关系(发动机-汽车)
创建内部类的语法:
在外部类内部创建内部类对象(Inner inner = new Inner());
在外部类外部创建内部类对象,外部类.内部类 inner = new Outter().new Inner();
静态内部类
定义:
在外部类的内部,使用static修饰,类比静态方法,静态内部类不需要外部类对象产生就能使用,不能访问外部类的成员域,但能访问静态域。
说明:
可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员。可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
静态内部类访问
外部类静态属性,访问方式:直接访问所有静态成员
外部类非静态,访问方式:创建对象,再访问
如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问
创建静态内部类的语法:
外部类内部:与成员内部类一样Inner inner = new Inner();
外部类外部:StaticInnerClass.Inner inner = new StaticInnerClass.Inner();
方法内部类
定义在方法内部:类比局部变量,对外部完全隐藏,因此方法内部类不能有任何访问修饰符,方法内部类没有访问形参,这个形参是可以在方法中随意修改的,一旦方法内部类中使用了形参,这个形参必须被声明为final。
说明:
局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。
可以直接访问外部类的所有成员,包含私有的,不能添加访问修饰符,因为它的地位就是一个局部变量。
局部变量是不能使用修饰符的,但是可以使用final修饰,因为局部变量也可以使用final。
作用域:仅仅在定义它的方法或代码块中。
局部内部类访问外部类的成员,访问方式:直接访问。
如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
外部类访问局部内部类的成员,访问方式:创建对象,再访问(注意:必须在作用域内)
外部其他类不能访问局部内部类,因为局部内部类地位是一个局部变量。
匿名内部类
必须继承一个抽象类或者实现一个接口
没有构造方法
本质是类
该类没有名字
同时还是一个对象
说明:
匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名
匿名内部类的基本语法
new类或接口(参数列表){
类体
};
匿名内部类的语法比较奇特,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,它既有定义类的特征,也有创建对象的特征,因此可以调用匿名内部类方法。
可以直接访问外部类的所有成员,包含私有的,不能添加访问修饰符,因为它的地位就是一个局部变量,作用域:仅仅在定义它的方法或代码块中。
匿名内部类访问外部类成员,访问方式:直接访问。如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
外部其他类不能访问匿名内部类(因为匿名内部类地位是一个局部变量)
11.抽象类abstract
抽象类
public abstract class Employee{}
所谓的抽象类就是没有实例对象的类。
abstract 不可以和static、virtual、final、native一起使用。
abstract修饰符可以用来修饰方法和类。如果修饰方法,那么该方法为抽象方法。
如果修饰类,则该类为抽象类。
抽象类中可以没有修饰方法,但抽象方法必须在抽象类中。
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么必须要实现抽象类的所有抽象方法,否则该子类也要声明为抽象类。
抽象类的特点:
不能new这个抽象类,只能靠子类去实现它
抽象类中可以写普通方法
抽象方法必须在抽象类中
子类继承抽象类,那么必须要实现抽象类的所有抽象方法
抽象方法
抽象方法只有方法名,没有方法体,否则报错。作为修饰符,abstract声明了一种没有具体对象的,出于组织概念的层次关系需要而存在的抽象类;作为类方法修饰符,abstract则声明了一种仅有方法头,而没有具体操作实现的方法体的抽象方法。
如:
abstract Boolean goVacation(int days);
可见,abstract方法只有方法头的声明,而用一个分号来代替方法体的定义;至于方法体的具体实现,那是由当前类的不同子类在他们各自的类定义中完成的。
12.接口interface
定义接口格式:
[public]interface 接口名称 [extends父接口名列表]
{
//静态常量
[public] [static] [final] 数据类型变量名=常量值;
//抽象方法
[public] [abstract] [native] 返回值类型方法名(参数列表);
}
实现接口格式:
[修饰符] class 类名[extends 父类名] [implements 接口A,接口B,···]
{
类成员变量和成员方法;
为接口A中的所有方法编写方法体,实现接口A;
为接口B中的所有方法编写方法体,实现接口B;
}
interface是面向对象编程语言中接口操作的关键字,功能是把所需成员组合起来,用来封装一定功能的集合。
- 接口相当于程序开发的一组协议,需要此功能的类均可“继承”该方法和集合。
- 接口的“继承”与类之间的继承不同,“继承”该接口的类,需要“自力更生”,去实现接口中的抽象方法,因此接口也相当于一个特殊的抽象类。
- 好比一个模板,在其中定义了对象必须实现的成员,通过类来实现它。
- 它是一种约束形式,不能包含成员的任何代码,只定义成员本身,也不能直接实例化,即ICount ic=new iCount()是错的。
- 用关键字interface定义接口,通过关键字implements来实现接口;
- 接口中的属性都是静态常量,方法都是抽象方法(即没有给出方法具体定义),一个类实现接口后,将继承接口中的所有静态常量。
- 接口中的成员变量具有公共性(public)、静态性(static)和最终性(final),修饰符只能是public,只能定义常量。
- 实现接口中的抽象方法时,方法头必须与接口定义中的方法头完全相同(包括访问控制修饰符、返回值类型、参数列表等)(例外:可去掉关键字abstract、接口定义时 public可缺省,但是实现时不可缺省)
实现多接口的类必须符合3个原则
能为所有的接口提供实现的功能;能遵循重写的所有规则;能保持相同的返回的数据类型。
13.package和import
package和import都是java的关键字;两个关键字都放在文件的最开始;在.java源文件中,一般package在前,import在后;
package
package指明该.java源文件中定义的类所在的包。若缺省该语句,则指定为无名包,相当于C++中的namespace,起到命名空间的作用,也就是防止命名冲突。
使用语法:package 母包.子包.子包。
import
import就相当于C/C++中的#include,起到导包的作用。
导入目标类后,该.java源文件就可以访问类中的方法和属性。
可以使用通配标识符 * 来一次导入多个包。
使用语法:import 母包.子包.子包。
14.访问控制权限
访问控制权限都有private私有的,protected受保护的,public公开的,默认的
private表示私有的,只能在本类中访问。
public表示公开的,在任何位置都可以访问。
“默认”表示只能在本类,以及同包下访问。
protected表示只能在本类、同包、子类中访问。
访问控制符 | 本类 | 同包 | 子类 | 任意位置 |
---|---|---|---|---|
public | 可以 | 可以 | 可以 | 可以 |
protected | 可以 | 可以 | 可以 | 不行 |
默认 | 可以 | 可以 | 不行 | 不行 |
private | 可以 | 不行 | 不行 | 不行 |
范围从大到小排序:public > protected > 默认 > private,访问控制权限修饰符可以修饰属性、方法、类、接口