1.abstract(抽象)修饰符
1.修饰类
(1)abstract修饰类,只能声明引用,不能创建对象
/* abstract修饰符(抽象的)
*/
package p1;
public class Test09{
public static void main(String[] args){
A a01=new A();//error!A类为抽象类不可实例化
System.out.println(a01.name);
}
}
//创建一个父类: A
abstract class A{
//初始化A类属性name为张三
String name="张三";
int age;
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
public void eat(){
System.out.println("A类的eat()方法");
}
}
运行结果:
(2)可以声明引用,例如A类为父类,可以调用A类的引用数据类型 创建子类B类的对象
/* abstract修饰符(抽象的)
*/
package p1;
public class Test09{
public static void main(String[] args){
A a01=new B();//体现abstract修饰符修饰的类可以声明
System.out.println(a01.name);
}
}
//创建一个父类: A
abstract class A{
//初始化A类属性name为张三
String name="张三";
int age;
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
public void eat(){
System.out.println("A类的eat()方法");
}
}
//B类继承A类
class B extends A{
public B(){
//测试代码块:作用是测试无参的B类构造方法是否运行
System.out.println("我是测试代码块/B类的无参构造方法");
}
}
运行结果
2.修饰方法(抽象方法)
(1).只有方法声明,无实现部分(有声明,没有方法执行体) 注:此处的方法全部不包括构造方法
/* abstract修饰符(抽象的)
*/
package p1;
public class Test09{
public static void main(String[] args){
A a01=new B();
System.out.println(a01.name);
}
}
//创建一个父类: A
abstract class A{
//初始化A类属性name为张三
String name="张三";
int age;
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
public abstract void eat(){//abstract修饰的抽象方法
System.out.println("A类的eat()方法");
}
}
运行结果:
(2)抽象方法只能在抽象类中定义
(有抽象方法的类一定是抽象类,但是抽象类不一定有抽象方法)
/* abstract修饰符(抽象的)
*/
package p1;
public class Test09{
public static void main(String[] args){
}
}
//有抽象方法的类一定是抽象类
abstract class A{
//初始化A类属性name为张三
String name="张三";
int age;
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
//抽象方法无方法执行体(无主体)
public abstract void eat()
}
//抽象类不一定有抽象方法
abstract class B {
public B(){
//测试代码块:作用是测试无参的B类构造方法是否运行
System.out.println("我是测试代码块/B类的无参构造方法");
}
}
(3)抽象方法可以被继承,子类需要覆盖父类的抽象方法,否则子类也是个抽象类
/* abstract修饰符(抽象的)
*/
package p1;
public class Test09{
public static void main(String[] args){
}
}
//抽象方法可以被继承,
//子类需要覆盖父类的抽象方法,否则子类也是个抽象类
abstract class A{
//初始化A类属性name为张三
String name="张三";
int age;
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
//抽象方法无方法执行体(无主体)
public abstract void eat();
}
//B类是一般类
class B extends A {
public void eat(){
//eat()方法重写父类的eat()抽象方法 这样class B 就可以不是abstract类
System.out.println("class B eat()");
}
}
结果:编译成功
特点:
(1)抽象类之间可以继承,抽象方法会一直叠加(怎么理解叠加呢?请看下边代码部分)
例如:A类是抽象类有抽象方法eat() ;B类是抽象类有抽象方法sleep()继承A类; C类继承B类 如果不想是抽象类,必须实现A类的抽象方法eat() 也必须实现B类的抽象方法sleep() 这样才能变成一般类 注:此处:实现=覆盖
//抽象方法可以被继承,
//子类需要覆盖父类的抽象方法,否则子类也是个抽象类
abstract class A{
//初始化A类属性name为张三
String name="张三";
int age;
public A(){
//测试代码块:作用是测试无参的A类构造方法是否运行
System.out.println("我是测试代码块/A类的无参构造方法");
}
//抽象方法 eat() 无方法执行体(无主体)
public abstract void eat();
}
//抽象类不一定有抽象方法
abstract class B extends A{
//抽象方法 sleep() 无方法执行体(无主体)
public abstract void sleep();
}
//一般类 C 继承了抽象类B
class C extends B{
//覆盖A的抽象方法eat()
public void eat(){
System.out.println("覆盖A的抽象方法eat()");
}
//覆盖B的抽象方法sleep()
public void sleep(){
System.out.println("覆盖B的抽象方法sleep()");
}
}
结果:编译成功
(2)private不能与abstract连用,意义冲突
private 意义为私人的 私有的 本身就不可继承
而abstract必须借助子类的实现才可以实现自己的价值
所以两者冲突
2.static修饰符
1.static修饰的属性
全类共有的属性(不属于某一个对象)
静态属性可以直接通过类名.属性名的方式进行访问
2.static修饰的方法
(1)无需创建对象,直接使用类名调用
(2)犹豫静态方法与对象无关,所有无法使用 this(当前)和super(父类、超类)关键字
(3)静态方法只能访问静态成员(成员的定义包括静态的属性和静态的方法)
3.static继承相关
(1)静态成员可以被继承
(2)静态方法只能被静态方法覆盖
(3)发生多态时,使用父类引用调用静态方法,只会执行父类中的静态方法
4.static修饰初始化代码块
在类加载时执行,在静态初始化代码块中可以为静态属性赋值
static不可与abstract连用
3.final最终的
修饰组件:局部变量 属性 类 方法
(1)修饰局部变量(最终变量)
特点:值不可变 基本数据类型 ,数据不可变;引用数据类型,地址不可变
(2)修饰属性(最终属性)
特点:值不变,无默认值必须手动赋值
赋值机会:①.声明同时赋值
②.初始化代码块赋值
③.构造方法赋值(保证每人构造方法中可以为final属性赋值 否则出现可能尚初始化错误)
注意:只能赋值一次
(3)修饰方法(最终方法)
特点:不可被覆盖,不可与abstract连用
(4)修饰类(最终类、断子绝孙类)
特点:不能被继承 没有子类
注:final修饰方法、修饰类可以提高程序的运行效率
三个不能连用要记清:
1. private和abstract不可连用
2.final和abstract不可出现
3.static和abstract不可出现
(多了解类加载的过程 会更加容易理解和巩固以上内容知识)