乐趣区

关于java:new了那么多对象你真的了解面向对象吗

一、面向过程和面向对象

1.1、面向过程

强调的是我该怎么去做。即性能的执行过程,即先干啥,后干啥。在面向过程中,咱们会写很多的函数,每一个函数负责实现某一个性能。

而一个主函数外面有多个小函数,须要实现某个性能的时候顺次调用即可

由此咱们发现面向过程的设计思维存在以下几个缺点:系统软件适应性差,可拓展性差,维护性低。

1.2、面向对象

一种基于面向过程的新的编程思维,顾名思义该思维是站在对象的角度思考问题,咱们把多个性能正当的放到不同对象里,强调的是我该让谁来做

面向对象最小的程序单元是类,必须先存在类的定义,再有对象,而具备某种性能的实体,称为对象

面向过程和面向对象的差异如下:

面向过程和面向对象各有千秋,面向对象更合乎咱们惯例的思维形式 ,稳定性好,可重用性强,易于开发大型软件产品,有良好的可维护性, 它领有三大特色:

  1. 封装
  2. 继承
  3. 多态

二、变量

2.1、变量的分类

依据变量定义的地位的不同,咱们大抵能够把变量分为两大类:

  1. 成员变量:间接定义在类中,办法的里面,又称之为 字段,不是属性
  2. 局部变量:除了成员变量外,其余变量都是局部变量,仅仅存在于办法内、代码块、办法的形式参数中

2.2、变量的初始值

变量的初始化示意在内存中开拓一个存储空间进行存储,只有初始化后才能够应用,不同的变量类型初始值不同

成员变量

默认是有初始值的,不同类型的初始值不同

数据类型 初始的默认值
byte、short、int、long 0
float、double 0.0
char 一个空字符(空格)“\u0000”
boolean false
援用数据类型 null(示意不援用任何对象

局部变量

局部变量没有初始值,必须手动初始化才能够应用

2.3、变量的作用域

变量依据定义的地位不同,也决定了各自的作用域是不同的,要害是看变量所在的花括号的地位

成员变量

在所定义的类中都无效

局部变量

从开始定义的地位到花括号内无效,花括号外就有效了

2.4、变量的生命周期

变量的生命周期,艰深的来说就是变量在内存中能够存活多久

成员变量

成员变量是属于对象的,对象在堆内存中,所以成员变量也是存储在堆内存中的,随着对象的 1 沦亡而沦亡

局部变量

局部变量是存储在栈内存的,随着办法的调用的完结而沦亡

局部变量是存储在办法中的,每次调用办法都会在栈空间开拓一个内存空间,咱们成为栈帧,办法 1 调用完结,栈帧就被销毁了,内存中存储的变量数据也就销毁了

三、类

3.1、类的定义

类是领有雷同个性(状态)和行为(性能)的多个对象的形象

  • 应用成员变量来示意状态
  • 应用成员办法来示意行为

格局

public class 类名{
    // 可编写 0 到 N 个成员变量
   修饰符 数据类型 变量名 1;
   修饰符 数据类型 变量名 2;
    
    // 可编写 0 到 N 个成员办法
    修饰符 返回值类型 办法名称(参数){// 办法体}
}

留神:

  1. 成员办法和变量 都不能够用 static 润饰,修饰符不是必须的
  2. 在形容对象的类中,不须要定义 main 办法,main 办法在专门的测试类中编写,切测试类和形容对象的类是离开编写的

四、对象

4.1、对象的创立

类名 对象遍历名 = new 类名();

如果咱们间接打印对象的话,打印的是相似数组地址的 hashCode 值

4.2、匿名对象

创建对象之后没有赋值给某个遍历,只能应用一次

new 类名();

4.3、给字段设置数据

对象变量名. 字段名 = 值;

4.4、获取字段的数据

数据类型 变量 = 对象变量. 字段名;

4.5、对象调用办法

对象变量名. 办法(参数);

4.6、对象实例化的内存剖析

以上面简略地 Cat 类进行剖析

public class Cat(){
    String name;
    int age;
}

创建对象

Cat cat = new Cat();

此时如果通过查看对象的 name 和 age 属性能够发现别离为初始值 null 和 0

给对象赋值

cat.name="xiaolin";
cat.age=18;

对象调用办法

public class Cat(){
    String name;
    int age;
    public void say(){System.out.println("咱们一起学猫叫");
    }
}

五、结构器(构造方法)

5.1、结构器的定义

结构器,也称之为构造方法(Constructor),作用是用来创建对象和给对象做初始化操作,只能在创建对象的时候应用一次

结构器的语法

public 类名(参数){// 办法体}

// 示范:public class Cat {public Cat() { }
    // 省略其余代码
}

结构器的特点

  1. 结构器名称和类名雷同
  2. 不能定义返回类型
  3. 结构器中不能呈现 return 语句

5.2、默认结构器

咱们在创立类的时候,没有手动写结构器,而没有报错,起因是因为如果咱们在编写对象的时候,如果没有写结构器的话,编译器会在编译源文件的时候,主动创立一个默认结构器,默认结构器的特点:无参数、无办法体。

如果类应用了 public 润饰,那么他默认的结构器也会应用 public 润饰,反之亦然

5.3、结构器的应用

没有结构器之前

之前,咱们是先通过一个默认参数结构器,先创立出一个对象再初始化(给字段设置值)

Cat cat = new Cat();
c.name = "xialin";
c.age = 18;

有了结构器之后

有了结构器之后,能够间接通过结构器同时实现对象创立和初始化操作

public class Cat {
    String name;
    int age;

    public Cat(String name, int age) {
        this,name = name;
        this.age = age;
    }

    void say() {System.out.println("我是" + name + ", 往年" + age + "岁");
    }
}
Cat cat = new Cat("zs", 19);
cat.say();

Cat cat = new Cat();    //    此行报错

当本人定义出结构器之后,编译器不再创立默认的结构器了,所以就不再主动有无参结构器,咱们个别在开发中无参结构器和有参结构器会同时编写,他们形成重载关系

public class Cat {
    String name;
    int age;
    // 无参数结构器
    public Cat() {}
    // 带参数结构器
    public Cat(String name, int age) {
        this,name = name;
        this.age = age;
    }
    // 其余代码
}

六、封装

封装是面向对象三大特色之一,其含意有两个(把握思维):

  • 把对象的字段和办法寄存在一个独立的模块中(类)
  • 信息暗藏,尽可能暗藏对象的数据和性能的实现细节

封装的益处:

  • 保证数据的安全性,避免调用者 随便 批改数据
  • 进步组件的重用性,把专用性能放到一个类中,谁须要该性能,间接调用即可

限度字段不可能随便批改的利器就是拜访修饰符

6.1、拜访修饰符

拜访修饰符,决定了有没有权限拜访某个资源,封装的实质就是要让有些类看不到另外一些类中定义的字段和办法。Java 提供了不同的拜访权限修饰符来限定类中的成员让谁能够拜访到

修饰符 类的外部 同一个包 子类 任何中央
private
protected
public
  • private:示意以后类是公有的,只能在本类中拜访,来到本类之后就不能间接拜访
  • 不写:示意以后包公有,定义和调用只能在同一个包中,能力拜访
  • protected:示意子类拜访权限,同一个包的能够拜访,即便不同包然而有继承关系也是能够拜访的
  • public:示意公共的,能够在以后我的项目的任何中央拜访

个别在开发中都是提供公有属性,裸露私有的拜访办法

6.2、JavaBean 标准

JavaBean 是一种某些符合条件的非凡类,然而必须遵循肯定的标准:

  1. 类必须应用 public 润饰
  2. 必须保障有公共无参数结构器,即便手动提供了带参数的结构器,也得手动提供无参数结构器
  3. 段应用 private 润饰,每个字段提供一对 getter 和 setter 办法
public String getName(){return   name;    // 返回 name 字段存储的值}
public void setName(String  n){name = n;    // 把传过来的参数 n 的值, 存储到 name 字段中}

6.3、结构器和 setter 办法

结构器和 setter 办法都能够给对象设置数据:

  • 结构器,在创建对象的时候设置初始数据,只能初始化一次。
  • setter 办法,创建对象后再设置初始数据,能够设置屡次。

七、继承

面向对象的继承思维,能够解决多个类存在独特代码的问题

  • 被继承的类,称之为父类、基类
  • 继承父类的类,称之为子类,拓展类
  • 父类:寄存多个子类独特的字段和办法
  • 子类:寄存本人特有的字段和办法

7.1、继承的语法

在程序中,如果一个类须要继承另一个类,此时应用 extends 关键字

public class 子类名 extends 父类名{}

留神:Java 中类只反对单继承,不反对多继承,然而反对多重继承。也就是说一个子类只能有一个间接的父类,父类也能够再有父类。一个父类也能够有多个子类

class Student1();
class Student2();
class Student extend Student1,Student2(){}// 谬误

Object 类是 Java 语言的根类,任何类都是 Object 的子类,要么是间接子类,要么是间接子类

7.2、子类能够继承到父类哪些成员

子类继承父类之后,能够领有到父类的某一些成员(字段和办法),依据拜访 修饰符 来判断:

  1. 父类中用 publicprotected润饰的成员,子类均能够继承
  2. 如果父类和子类在同一个包中,应用缺省拜访润饰的成员,此时子类能够继承到
  3. 如果父类中的成员用 private 润饰,子类继承不到,因为 private 只能在奔本类中拜访
  4. 父类的结构器,子类也无奈继承,因为结构器必须和类名雷同

7.3、办法的重写

当子类存在一个和父类截然不同的办法时,咱们就称之为子类笼罩了父类的办法,也称之为重写。那么咱们就能够在子类办法体中,重写编写逻辑代码

办法调用的程序为:通过对象调用办法时,先在子类中查找有没有对应的办法,若存在就执行子类的,若子类不存在就执行父类的,如果父类也没有,报错。

办法重写须要留神的点:

  1. private 润饰的办法不能被子类所继承,也就不存在重写的概念
  2. 实例办法签名必须雷同(办法签名 = 办法名 + 办法参数列表)
  3. 子类办法的返回值类型和父类的返回值类型雷同或者是其子类
  4. 子类办法中申明抛出的异样小于或者等于父类办法申明抛出的异样类型
  5. 子类办法的拜访权限比父类的拜访权限更大或者相等
  6. 个别开发都是间接拷贝父类的办法定义粘贴到子类中,从新编写子类的办法体

7.4、super 关键字

在子类中的某一个办法中须要去调用父类中被笼罩的办法,此时得应用 super 关键字。

如果调用被笼罩的办法不应用 super 关键字,此时调用的是本类中的办法。super 关键字示意父类对象的意思

7.5、形象

形象办法用 abstract 来润饰办法,被 abstract 润饰的办法具备两个特色:

  1. 该办法没有办法体
  2. 要求子类必须笼罩该办法

7.5.1、形象办法

应用 abstract 润饰的办法,称为形象办法

public abstract 返回类型 办法名(参数);

形象办法的特点:

  1. 应用 abstract 润饰,没有办法体,留给子类去笼罩
  2. 形象办法必须定义在抽象类或者接口中

7.5.2、抽象类

应用 abstract 润饰的类,称为抽象类

public abstract class 类名{}

抽象类的特点:

  1. 抽象类不能创建对象,调用没有办法体的形象办法没有任何意义
  2. 抽象类中能够同时领有形象办法和一般办法
  3. 抽象类必须有子类才有意义,子类必须笼罩父类的形象办法,否则子类也得作为抽象类

7.6、Object 类和罕用办法

Object 自身示意对象的意思,是 Java 中的根类,要么是一个类的间接父类,要么就是一个类的间接父类。任何类都间接(间接)继承了 Object 类

class  A{}  
// 等价于
class  A extends Object{}

因为所有类都是 Object 类的子类,所有类的对象都能够调用 Object 类中的办法,常常应用的办法有

7.6.1、boolean equals(Object obj)

boolean equals(Object obj):拿以后调用该办法的对象和参数 obj 做比拟

在 Object 类中的 equals 办法和“==”符号雷同,都是比拟对象是否是同一个的存储地址。

public class ObjectDemo {public static void main(String[] args) {
        // 创立 Person 对象 p1
        Person p1 = new Person();
        // 创立 Person 对象 p2
        Person p2 = new Person();
        
        // 比拟 p1 和 p2 的内存地址是否雷同
        boolean ret1 = p1 == p2;
        boolean ret2 = p1.equals(p2);
        System.out.println(ret1);    //false
        System.out.println(ret2);    //false
    }
}

7.6.2、toString 办法

toString 示意把对象中的字段信息转换为字符串格局

打印对象其实就是打印对象的 toString()办法,然而 toString()办法默认打印的是对象的 hashCode 的值

com._04_object.Person@15db9742  

所以个别咱们都会重写 toString()办法

    public String toString() {return "Person [name=" + name + ", age=" + age + "]";
    }

7.7、== 符号详解

每一次应用 new 关键字,都示意在堆内存中创立一块新的内存空间

  • 如果是根本数据类型:比拟的是两个值是否相等
  • 如果是对象数据类型:比拟的是是否为同一块内存地址

八、多态

8.1、接口

​ 接口是一种约定标准,是多个形象办法的汇合。仅仅只是定义了应该有哪些性能,自身不实现性能,至于每个性能具体怎么实现,就交给实现类实现。

​ 接口中的办法是形象办法,并不提供性能实现,体现了标准和实现相拆散的思维,也体现了组件之间低耦合的思维。接口仅仅提供办法的定义,却不提供办法的代码实现

​ 所谓耦合度,示意组件之间的依赖关系。依赖关系越多,耦合性越强,同时表明组件的独立性越差,在开发中往往提倡升高耦合性,可进步其组件独立性,举一个很简略的例子:

  • 集成显卡:显卡和主板焊死在一起,显卡坏了,只能换主板
  • 独立显卡:显卡和主板相拆散,显卡插到主板上即可,显卡坏了,只换显卡,不必换主板

8.1.1、接口的定义

接口能够认为是一种非凡的类,然而定义类的时候应用 class 关键字,定义接口应用 interface 关键字,接口中的办法都是公共的形象办法

public    interface  接口名{// 形象办法 1();
    // 形象办法 2();
    // 形象办法 2();}    

留神:从 Java 8 开始, Java 反对在接口中定义有实现的办法

public interface IMan {public abstract void walk();// 形象办法
    
    default void defaultMethod(){System.out.println("有默认实现的办法, 属于对象");
    }
    static void defaultMethod(){System.out.println("有默认实现的办法, 属于类");
    }
}

类能够继承类,然而只能单继承的,接口也能够继承接口,然而却能够继承多个接口 ,也就是说 一个接口能够同时继承多个接口

8.1.2、接口实现类

和抽象类一样,接口是不能够创建对象的,如果想实现接口的性能,就必须定义一个类去实现接口,并且笼罩接口中的所有办法,这个类称为实现类,这品种和接口的关系称为实现关系

public class 类名 implements 接口名{// 笼罩接口中形象办法}
  • 接口:定义多个形象办法,仅仅定义有哪些性能,不做任何实现
  • 实现类:实现接口,重写接口中的形象办法,实现具体性能的实现

8.2、多态

在继承关系,是一种”is A”的关系,也就说子类是父类的一种非凡状况

public class Animal{}
public class Dog extends Animal{}
public class Cat extends Animal{}

此时咱们能够认为猫和狗都是一种非凡动物,那么能够应用动物类型来示意猫或者狗

Dog     dog     =     new Dog();      // 创立一只狗对象, 赋给子类类型变量
Animal  animal      =    new Cat();        // 创立一只猫对象, 赋给父类类型变量

此时对象 animal 具备两种类型:

  1. 编译类型:申明对象时候的类型(Animal)
  2. 运行类型:对象实在的类型(Cat)

当编译类型和运行类型不统一的时候,多态就产生了

所谓的多态就是示意一个对象有多种状态,简略来说就是 同一援用类型,因为援用的实例不同,对同一办法产生的后果也不同

Person person = null;
person = new Man();    //person 此时示意 Man 类型
person = new Woman();//person 此时示意 Woman 类型

多态肯定建设在办法重写或者实现之上,能够是继承关系(类和类),也能够是实现关系(接口和实现类),在开发中,个别都指接口和实现类之间的关系,多态在在开发中有两种定义格局

8.2.1、操作继承关系(开发中不是很多)

父类援用变量指向于子类对象,调用办法时理论调用的是子类的办法

父类 变量名 = new 子类();
变量名. 办法();

Animal 类:

public class Animal {public void shout() {System.out.println("动物... 叫...");
    }
}

Cat 类:

public class Cat extends Animal{public void shout() {System.out.println("猫叫...");
    }
}

Test 类:

public class AnimalDemo{public static void main(String[] args){Animal animal = new Cat();
        animal.shout();}
}

运行后果:

猫叫

8.2.2、操作实现关系

接口 变量名 = new 实现类();
变量名. 办法();

ISwimable 接口:

public interface ISwimable{void swim();
}

Fish 类:

public class Fish implements ISwimable{}
    public void swim(){Sysout.out.println("鱼在游")
    }
}

Test 类:

public class Fish implements{public static void main(String[] args){ISwimable fish = new Fish();
       fish.swim();}
}

后果:

鱼在游泳

8.2.3、多态中办法调用问题

如果咱们把子类对象赋值给父类对象

Animal animal = new Cat();
animal.shout();

那么 animal 对象在调用 shout 办法的时候,他调用的是子类本人的办法还是父类的办法呢?

咱们能够看得出,在编译期间,JVM 会先去找父类的办法,如果找到了就去找子类的同名办法,如果子类也有就运行子类的办法,否则就运行父类的办法,如果连父类的办法都没有找到的话,间接编译失败。

8.2.4、类型转换和 instanceof 运算符

8.2.4.1、主动类型转换

主动类型转换:把子类对象赋给父类变量(多态)

Animal a = new Dog();
Object  obj = new Dog();    //Object 是所有类的根类

8.2.4.2、强制类型转换

把父类类型对象赋给子类类型变量(前提:该对象的实在类型应该是子类类型)

当须要调用子类特有的办法时,必须通过强制类型转换,不过有一个要求:父类必须是实在的子类类型才能够转换

Animal a = new Dog();
Dog    d = (Dog) a;// 正确
Cat c = (Cat) a;// 谬误,实在类型为 Dog

8.2.4.3、instanceof 运算符

判断该对象是否是某一个类的实例

语法格局

boolean b = 对象 A   instanceof  类 B;  // 判断 A 对象是否是 B 类的实例?如果是, 返回 true

8.2.4.4、多态总结

面向接口编程,体现的就是多态,其益处:把实现类对象赋给接口类型变量,屏蔽了不同实现类之间的实现差别,从而能够做到 通用 编程

8.3、面试题

接口和抽象类的区别

  1. 接口中所有的办法隐含的都是形象的,然而抽象类中能够同时蕴含形象办法和一般办法以及动态常量
  2. 类能够实现很多个接口,然而只能继承一个抽象类
  3. 类如果要实现一个接口,那么他必须要实现接口申明的所有办法,然而类能够不实现抽象类中的所有办法,然而这个类必须是抽象类
  4. 接口中不存在构造方法,因为接口的成员变量都是 static final 变量,是在编译的时候就实现了初始化操作了,无需通过构造方法来进行初始化操作,而抽象类必须有构造方法
  5. 抽象类和接口的概念的区别:

    • 抽象类是从一些类中抽取他们的共有的属性,办法的修饰符能够是 public 或者是 protected 以及缺省,抽象类重视对类自身的形象,形象办法没有办法体,仅仅是申明了该办法,让继承他的子类去实现
    • 接口次要是对类的行为形象,接口也能够有变量和办法,然而变量以及办法的修饰符必须是 public static final(缺省时会默认加上)和 public abstract(缺省时默认也是这个)

九、关键字(this、super)

9.1、this 关键字

this关键字示意以后对象(谁调用 this 所在的办法,this 就是哪一个对象次要)存在于两个地位:

  1. 在结构器中:示意以后创立的对象
  2. 在办法中:哪一个对象调用 this 所在的办法,此时 this 就示意哪个对象

什么时候须要应用 this 关键字

  1. 为了解决局部变量和成员变量之间的二义性,此时必须应用
  2. 同一个类中非 static 办法之间的相互调用,此时能够省略,然而根本不会省略
  3. 调用本类其余的构造方法
public class Dog {
    private String name;
    private int age;

    public Dog() {}

    public Dog(String name) {this(name, 0);// 调用两个参数的结构器(结构器之间的重载), 必须放在结构器第一行
    }

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void say() {
        String name = "局部变量";
        System.out.println(name); // 拜访局部变量
        System.out.println(this.name);// 拜访成员变量
        this.other();// 调用以后类中非 static 办法}

    public void other() {System.out.println(this.age);// 此时的 this 是谁
    }
}

this 内存图

this 关键字示意以后对象自身,个别用于类的外部,其外部存在一个地址,指向以后初始化对象自身

当 new 一个对象的时候,实际上产生了两个援用,一个是供 Dog 外部调用其余成员变量或者成员办法的 this 关键字,另一个是供外界程序调用实例成员的 dog 持有类信息

9.2、super 关键字

super 示意以后对象的父类对象,在创立子类对象的时候,在子类结构器的第一行会先调用父类的结构器

super 尽管示意父类对象,然而他仅仅只是一个关键字,外部并没有地址,所以不可能援用

什么时候应用 super

  1. 拜访父类中非公有的实例办法,此时必须应用 super
  2. 在子类的结构器中,调用父类的结构器,此时必须应用 super
  3. 如果想拜访父类的非公有成员变量,此时必须应用 super

父类:

public class Person {
    private String name;
    private int age;

    public Person() {}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void doWork() {System.out.println("Person...doWork...");
    }
}

子类:

public class Student extends Person {
    private String sn;

    public Student(String sn) {super();// 隐式调用父类无参数结构器, 必须作为结构第一行
        this.sn = sn;
    }
    public Student(String name, int age, String sn) {super(name, age);// 显示去调用父类有参数结构器, 必须作为结构第一行
        this.sn = sn;
    }
    public void doWork() {super.doWork();    //    此时调用父类的 doWork()办法
        this.doWork();    //    此时调用本人的 doWork()办法
        System.out.println("Student...doWork...");
    }
}

总结

  1. super 调用构造方法必须写在子类构造方法的第一行
  2. 如果子类构造方法没有显示调用父类构造方法时,那么 JVM 会默认调用父类的无参结构器

十、修饰符(static、final)

10.1、static 修饰符

static 润饰的字段和办法都间接属于类,不属于该类的对象(字段和办法属于谁,就让谁来调用)

  • 有 static 润饰的变量和办法:属于类,间接用类名调用即可,在同一个类中调用能够省略类名不写
  • 没有 static 润饰的变量和办法:属于对象,必须先创建对象,而后用对象调用

留神:static 办法不能应用 super 和 this 关键字

因为 static 是类级别的,super 和 this 是对象级别的,存在类的时候不肯定存在对象,也就说应用类名调用 static 办法时,此时可能是没有对象的。

10.1.1、静态方法

static 润饰的办法称为静态方法,归类所有,也称为类办法

修饰符 static 返回值类型 办法名(形参列表){}

静态方法有两种拜访形式:

  1. 类名. 静态方法名()
  2. 对象. 静态方法名()Java 是不举荐这种拜访机制的

静态方法的个性

  1. 静态方法中能够拜访动态变量和其余静态方法
  2. 实例办法中能够拜访动态成员变量以及动态成员办法

10.1.2、动态变量

在类中,用 static 关键字润饰的成员变量 称为动态变量,归类所有,也称为类变量,类的所有实例对象都能够拜访,被类的所有实例或者对象共享

static 数据类型 成员变量

动态变量的拜访

  1. 类名. 动态变量
  2. 类的对象. 动态变量(Java 不举荐

10.2、final 修饰符

final 的含意是 最终的,不可扭转的 ,能够润饰类、办法、变量,他是来限度 某个类不能够有子类,不能够笼罩办法

final 润饰的类

示意最终的类,该类不能够再领有子类

final public class Super {
}
public class Sub  extends Super{// 此行语法报错}

final 润饰的办法

最终的办法,该办法不能够被子类笼罩

public class Super {final public void doWork() {}}

public class Sub  extends Super{public void doWork() {// 此行语法报错}
}

final 润饰的变量

示意常量,该变量只能赋值一次,不能够再从新赋值

  • 根本数据类型:示意的值不能再扭转
  • 援用数据类型:所援用的地址不能够再扭转
final int age = 17;
age = 100;    // 此行语法报错

final Dog d = new Dog();
d.setAge(5);    // d 的字段值是能够扭转的    
d = new Dog();    // 此行语法报错

十一、代码块

间接应用 {} 括起来的一段代码区域,代码块外面的变量属于局部变量,仅在 {} 内无效

他有三种存在模式:一般代码块、结构代码块、动态代码块

11.1、一般代码块

间接定义在办法外部的代码块,个别的,不会间接应用部分代码块的,联合 if、while、for 等关键字应用,示意一块代码区域,作用域能够嵌套

public class CodeBlockDemo {public static void main(String[] args) {System.out.println("begin...");
        {
            // 间接应用代码块,个别不必
            int age = 17;
        }
        System.out.println(age);    // 此行报错, 超出 age 作用范畴, 就不能拜访到了
        if (100 > 5) {System.out.println("100 > 5");
        }
        System.out.println("end...");
    }
}

11.2、结构代码块

结构代码块在类的外部,办法的内部,随着一个对象的创立而执行一次,在构造方法前执行

package day09_ObjectAdvanced.Classing.StaticBlock;

/**
 * @author Xiao_Lin
 * @version 1.0
 * @date 2020/12/9 16:29
 */
public class Dog {
  private String name;
  static String age="111";

  {System.out.println("我是结构代码块");
  }
  public Dog(){System.out.println("我是无参构造方法");
  }

  public Dog(String name){System.out.println("我是有参构造方法");
  }

  public void shut(){System.out.println("我是叫办法");
  }

}

如果须要在构造方法执行前加载一些资源(如读配置文件、XML 文件等等),咱们能够把结构对象前的所有操作都放在结构代码块中执行

11.3、动态代码块

用 static 关键字所润饰的代码块称为动态代码块,位于类的外部、办法的内部,且只执行一次,在结构代码块、构造方法前执行

package day09_ObjectAdvanced.Classing.StaticBlock;

/**
 * @author Xiao_Lin
 * @version 1.0
 * @date 2020/12/9 16:29
 */
public class Dog {
  private String name;
  static String age="111";

  static {System.out.println("我是动态代码块");
  }

  {System.out.println("我是结构代码块");
  }
  public Dog(){System.out.println("我是无参构造方法");
  }

  public Dog(String name){System.out.println("我是有参构造方法");
  }

  public void shut(){System.out.println("我是叫办法");
  }

}

十二、外部类

12.1、类的组织形式

12.1.1、类和类的平行关系

一个文件能够定义多个类,但只能存在一个 public 类,且文件的名字和 public 类的名字要保持一致

public class Dog{ }
class Cat{}


Dog 和 Cat 位置一样,和离开定义两个文件是截然不同的

12.1.2、类和类之间蕴含关系

public class Outer {public class Inner{}
}

Outer 和 Inner 是蕴含关系,Outer 称为外部类,而 Inner 称为外部类,外部类 Inner 作为一个 Outer 的成员而存在

12.2、外部类的概述

什么是外部类,把一个类定义在另一个类的外部,把外面的类称之为外部类,把里面的类称之为外部类,外部类的分类有:

  1. 成员外部类
  2. 动态外部类
  3. 办法外部类
  4. 匿名外部类

12.3、匿名外部类

当一个类只应用一次,能够申明成匿名外部类

匿名外部类 必须有实现存在,多以实现接口居多

public class Outer {public void print(){
/*
class Inner implements AInterface{
@Override
public void showInfo() {System.out.println("inner.showInfo");
}
}
new Inner().showInfo();
*/
      
/*
AInterface aInterface = new AInterface(){
@Override
public void showInfo() {System.out.println("inner.showInfo");
}
};
aInterface.showInfo();
*/
      
// 通过匿名类创立匿名对象
    new AInterface(){
      @Override
      public void showInfo() {System.out.println("inner.showInfo");
      }
    }.showInfo();}
}

十三、枚举类

枚举是一种非凡的类,固定一个类只能有哪些对象

13.1、枚举类的定义

public enum 枚举类型{常量对象 A、常量对象 B、常量对象 C}
publicc enum Story{HISTORY、ENGLISH、MATH}

咱们自定义的枚举类都是在底层间接继承了 java.lang.Enum 类,枚举中都是全局公共的动态常量,能够间接用枚举类名调用

Stroy story = Story.ENGLISH;

因为 java.lang.Enum 类是所有枚举类的父类, 所以所有的枚举对象能够调用 Enum 类中的办法

String    name = 枚举对象.name();          //    返回枚举对象的常量名称
int    ordinal  = 枚举对象.ordinal();    //    返回枚举对象的序号, 从 0 开始

留神:枚举类不能应用创建对象

退出移动版