三个修饰符
一、abstract
1.1什么是抽象
- 似是而非的,像却又不是;具有某种特征,但不完整
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNUP8nDM-1666399884721)(D:\Folder\笔记\img\抽象1.png)]
- 现实世界中,都是动物的子对象,而没有动物对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xIEDS1cs-1666399884722)(D:\Folder\笔记\img\动物.jpg)]
问题思考:
public class Animal {
private String variety;//品种
private int age;//年龄
private String gender;//性别
//get和set
public void eat() {
System.out.println("吃");
}
public void sleep() {
System.out.println("吃");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
}
}
Animal
仅是一种会吃会睡的对象,再无其他行为,不够具体,不够完整Animal a = new Animal()
不应该被创建- 程序是用来模拟现实世界,解决实际问题的,现实世界中存在的都是动物具体的子类对象,并不存在动物对象,所以,
Animal
不应该被独立创建成对象 - 如何限制这种对象的创建?
1.2抽象类
abstract
修饰类,此类不能new
对象- 被
abstract
修饰的类,称为抽象类 - 抽象类意为不够完整的类、不够具体的类,抽象类对象无法独立存在,即不能new对象
public abstract class Animal {
private String variety;//品种
private int age;//年龄
private String gender;//性别
public void eat() {
System.out.println("吃");
}
public void sleep() {
System.out.println("吃");
}
}
作用:
- 可被子类继承,提供共性属性和方法;
- 可声明为引用,更自然的使用多态
经验:
- 抽象父类,可作为子类的组成部分,依附于子类对象存在,由父类共性+子类独有属性和方法组成完整的子类对象
1.3抽象方法
public class Animal {
private String variety;//品种
private int age;//年龄
private String gender;//性别
public void eat() {
System.out.println("吃");
}
public void sleep() {
System.out.println("睡");
}
}
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗在吃");
}
@Override
public void sleep() {
System.out.println("狗在睡");
}
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫在吃");
}
@Override
public void sleep() {
System.out.println("猫在睡");
}
}
Dog
中的eat()
应输出狗在吃
Cat
中的eat()
应输出猫在吃
父类提供的方法很难满足子类不同需求,如不定义,则表示所有动物都不会吃、睡。如果定义,略显多余,多数会被子类覆盖。
抽象方法的声明是必要的,而没必要实现的方法,可以定义为抽象方法
public abstract class Animal {
private String variety;//品种
private int age;//年龄
private String gender;//性别
public abstract void eat();
public abstract void sleep();
}
1.4总结
-
abstract
修饰是类是抽象类,不能new
对象,可以被继承,也可以声明引用 -
abstract
修饰方法是抽象方法,只有方法声明,没有方法体,包含在抽象类中 -
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
-
子类继承抽象类后,必须重写父类中所有的抽象方法,否则子类还是抽象类
二、static
2.1、什么是静态
-
static(静态)
可以修饰属性、方法、代码块、内部类 -
被
static
修饰的属性称为静态属性(类属性),被static
修饰的方法称为静态方法(类方法) -
静态成员是全类所有对象共享的成员,在全类中只有一份,不因创建多个对象而产生多份
-
不需要创建对象,可直接通过类名访问,访问方式如下:
类名.成员
对象名.成员
2.2、静态属性
public class Student {
public int a; //实例属性
}
public class MyTest1 {
public static void main(String[] args) {
Student c1 = new Student();
c1.a = 20;
Student c2 = new Student();
c2.a = 30;
System.out.println("c1.a = " + c1.a);
System.out.println("c2.a = " + c2.a);
}
}
static变量的内存分配
静态属性是整个类共同持有的共享空间(一份),任何对象修改,都会影响其他对象
2.3静态方法
- static修饰方法:静态方法 类方法
- 调用方法通过类名调用
- 静态方法只能调用静态的属性以及静态方法
- 静态方法中不允许使用
this
和super
关键字 - 抽象方法不能使用static修饰
- 静态方法不能被重写可以被继承
- 静态方法不能使用abstract修饰(抽象方法必须被实现也就是重写)
2.4静态代码块
- 修饰代码块称之为静态代码块
- 静态代码块在类加载时就执行
- 优先于动态代码块
- 只会执行一次
2.5类加载的时机
- 在对象创建时会触发类加载
- 子类创建时会触发类加载
- 调用类的静态成员时会触发类加载
Class.forName
(“类的权限定名(包名+类名)”)主动触发类加载
public class X {
public X() {
System.out.println("父类实例属性");
}
}
public class Y {
public Y() {
System.out.println("父类静态属性");
}
}
public class M {
public M() {
System.out.println("子类实例属性");
}
}
public class N {
public N() {
System.out.println("子类静态属性");
}
}
public class SuperClass {
private X x = new X();
private static Y y = new Y();
//动态代码块
{
System.out.println("父类动态代码块");
}
//静态代码块
static {
System.out.println("父类静态代码块");
}
public SuperClass() {
System.out.println("父类构造方法...");
}
}
public class SubClass extends SuperClass {
private M m = new M();
private static N n = new N();
//动态代码块
{
System.out.println("子类动态代码块");
}
//静态代码块
static {
System.out.println("子类静态代码块");
}
public SubClass() {
System.out.println("子类构造方法...");
}
}
public class MyTest6 {
public static void main(String[] args) {
SubClass subClass = new SubClass();
System.out.println("***************************");
SubClass subClass1 = new SubClass();
}
}
执行结果:
父类静态属性
父类静态代码块
子类静态属性
子类静态代码块
父类实例属性
父类动态代码块
父类构造方法...
子类实例属性
子类动态代码块
子类构造方法...
***************************
父类实例属性
父类动态代码块
父类构造方法...
子类实例属性
子类动态代码块
子类构造方法...
三、final
final
:最终的,最终的,最后的,决定性的,不可改变的
-
final
可以修饰:-
变量(最终变量)
-
方法(最终方法)
-
类(最终类)
-
-
final
修饰的类,不能被继承String
、Math
、System
都被final
修饰,不能被继承
-
final
修饰的方法,不能被覆盖(重写) -
final
修改的变量,是常量,不能修改值- 所有
final
修改的变量只能赋值一次,值不允许改变。
- 所有