目录
类的封装
1.为什么要进行封装
2.如何实现封装
this关键字
1.解决成员变量和局部变量名冲突的问题
2.通过this调用成员方法
3.通过this调用构造方法
构造方法
构造方法的定义
构造方法的重载
代码块
静态代码块
实例代码块
Java中,针对类,成员方法和属性提供了四种访问级别private,default,protected,public
- private(当前类访问级别),如果说一个类的成员被private修饰,则这个成员只能被该类的其他成员访问,而其他类无法直接访问
- default(包访问级别),如果说一个类或者类的成员不使用任何控制符修饰,则称他为默认访问级别,这个类或者类的成员只能被本包的其他类访问
- protected(子类访问级别)如果一个类的成员被protected修饰,那么这个成员既可以被同一包下的其他类访问,也可以被其他包下的该类的子类访问
- public(公共访问级别)如果说一个类或者类的成员使用public修饰,那么这个类或者类的成员可以被所有的类访问,不管访问类和被访问类是不是在同一个包里
类的封装
1.为什么要进行封装
封装:属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限
封装的意义是:尽量避免向外部暴露实现细节,只提供个别接口让使用方调用。这样做的话,当自身的逻辑发生变化时,不会破坏使用方的逻辑,或是强制使用方修改自身的逻辑,而是只需要修改自身的代码就可以了
封装的本质是将事物相关的属性和方法封装在一个类里面,我们调用类创建实例的时候,不用关心类内部的代码细节,相当于一个黑箱子,我们只需要该实例(黑箱)能给出我们想要的结果就好了。
2.如何实现封装
定义一个类时,将类中的属性私有化,私有属性只能在它所在的类中被访问,如果说外部想要访问该属性,则需要提供一些公有方法
class Print{
private int age;
private String name;
public int fun() {
age=9;
return age;
//private修饰,age只能在定义age的类中使用,别的类使用,需要借用公开方法
}
}
public class texe {
public static void main(String[] args) {
Print p=new Print();
//System.out.println(p.age);
//private修饰,age只能在定义age的类中使用,别的类使用,需要借用公开方法
System.out.println(p.fun());
}
}
this关键字
1.解决成员变量和局部变量名冲突的问题
class Sout{
int age=8;//成员变量
public void print(int age) {//age是局部变量,形参9
age = age;//当局部变量和成员变量同名时,局部变量优先于全局变量
//9=9 成员变量仍是8
this. age = age;//this引用了成员变量
// 成员变量更改为9
}
}
public class texe {
public static void main(String[] args) {
Sout p=new Sout();
p.print(9);
System.out.println(p.age);
}
2.通过this调用成员方法
class Person {
int age=0;
public void print(int age){
this.age=age;
System.out.println(this.age);
}
public void speak(int age){
this.print(2);
}
}
class text {
public static void main(String[] args) {
Person p1 = new Person();
p1.speak(3);
}
}
main方法中调用speak方法,speak方法内调用print()成员方法,print()方法中,this.age调用成员变量,成员变量改为形参2的值
3.通过this调用构造方法
构造方法是在实例化对象时被自动调用的,在程序中不可以像调用普通方法那样调用构造方法,但是可以使用this在一个构造方法中调用其他的构造方法
class Person {
public Person(){
this(2);
System.out.println("这是一个没有参数的构造方法");
}
public Person(int age){
System.out.println("这是一个有参数的构造方法"+"传入形参="+age);
}
}
class text {
public static void main(String[] args) {
Person p1 = new Person();
}
}
在创建对象时,自动调用了无参数的构造方法,先执行this(2),调用了有参数的构造方法
注意事项:
1.只可以在构造方法中使用this调用其他构造函数,而不可以在成员方法中调用
class Person {
public void print(){//成员方法
this();//成员方法不能使用this调用构造方法
System.out.println("ok");
}
public Person(){//构造方法
System.out.println("hi");
}
public Person(int age){构造方法
System.out.println("hello");
}
}
class text {
public static void main(String[] args) {
Person p=new Person();
}
}
2.构造方法中,this必须是第一条语句,且只能出现一次
class Person {
public Person(){
System.out.println("hi");
this(10);
}
public Person(int age){
System.out.println("hello");
}
}
class text {
public static void main(String[] args) {
Person p=new Person();
}
}
class Person {
public Person(){
this(10);
System.out.println("hi");
this(20);
}
public Person(int age){
System.out.println("hello");
}
}
class text {
public static void main(String[] args) {
Person p=new Person();
}
}
3不能在一个类中的两个构造方法互相使用this调用
class Person {
public Person(){
this(10);
System.out.println("hi");
}
public Person(int age){
this();
System.out.println("hello");
}
}
class text {
public static void main(String[] args) {
Person p=new Person();
}
}
构造方法
构造方法的定义
如果说需要在实例化对象的同时就为这个对象的属性进行赋值,可以使用构造方法来实现。
构造方法是类的一个特殊成员,它会在类实例化对象时被自动调用。
构造方法的定义
【修饰符】方法名(方法参数){
方法体
}
要求:
- 方法名和类名相同
- 方法名的前面没有返回类型
- 不能使用return返回一个值,但是可以单独写return语句来结束方法
class Person{
int age;
public Person (){
System.out.println("这是个构造方法");
}
}
class text {
public static void main(String[] args) {
Person p=new Person();
}
}
在这个代码中,会打印:这是个构造方法
在Person这个类中,定义了一个无参数的构造方法 Person,执行Person p=new Person();创建Person对象时会自动调用构造方法
构造方法的重载
构造方法之间也可以构成重载
class Person{
int age;
public Person (){
System.out.println("这是个构造方法");
}
public Person (int s){
System.out.println("这是个有参数构造方法"+s);
}
}
class text {
public static void main(String[] args) {
Person p = new Person();
Person p1 = new Person(3);
}
}
java的每一个类中至少会有一个构造方法:如果说在一个类中没有定义构造方法,系统会自动地为这个类创建一个默认的构造方法,这个默认的构造方法没有参数,方法体中也没有任何代码。一旦为该类定义了构造方法,系统将不会提供默认的无参数构造方法
class Person{
int age;
public Person (int s){
System.out.println("这是个有参数构造方法"+s);
}
}
class text {
public static void main(String[] args) {
Person p1 = new Person(3);
Person p = new Person();
}
}
原因: Person类中已经创建了有参数的构造方法,这时,系统不会提供默认的无参数构造方法。所以:如果说一个类里面如果已经定义了有参数的构造方法,那么最好再定义一个无参数的构造方法
class Person{
int age;
public Person (int s){
System.out.println("这是个有参数构造方法"+s);
}
public Person (){
System.out.println("这是个有参数构造方法");
}
}
class text {
public static void main(String[] args) {
Person p1 = new Person(3);
Person p = new Person();
}
}
代码块
在java类中,{ }括起来的若干行代码被统称为代码块
静态代码块
被static修饰的代码块称之为静态代码块
实例代码块
class Person {
public Person(){
System.out.println("这是一个没有参数的构造方法");
}
{
System.out.println("这是一个实例代码块");
}
static{
System.out.println("这是一个静态代码块");
}
}
class text {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println("==============");
Person p = new Person();
}
}
class Person {
static void print(){
System.out.println("这是一个没有参数的构造方法");
}
static {
System.out.println("这是一个静态代码块");
}
{
System.out.println("这是一个实例代码块");
}
}
class text {
public static void main(String[] args) {
Person.print();
}
}
结论:静态代码块就算不实例化对象,都会被加载,且只会被加载一次。
加载一个类,先会加载类里面的静态代码块,其次是实例代码块,后是其他方法(和相对位置无关)
但是,如果都是静态变量/都是全局变量,和相对位置有关
class Person {
public static int age = 20;
static {
age = 10;
}
}
class text {
public static void main(String[] args) {
Person p=new Person();
System.out.println(p.age);
}
}
结果:10,即先执行 public static int age = 20;
class Person {
static {
age = 10;
}
public static int age = 20;
}
class text {
public static void main(String[] args) {
Person p=new Person();
System.out.println(p.age);
}
}
结果:20,即后执行 public static int age = 20;
但是,有一种特殊情况,当不初始化时,结果和相对顺序无关
class Person {
static {
age =5;
}
public static int age ;
}
class Person {
public static int age ;
static {
age =5;
}
}
结果都是5