JAVA面向对象关键字

1.this(当前对象的/或/构造器正在初始化的对象)

 

1.他在方法内部使用,即这个方法所属对象的引用

2.它在构造器内部使用,表示"该构造器正在初始化的对象"

3.this表示"当前对象的"//"this表示当前引用(注意不是当前对象)",可以调用类的属性、方法和构造器

   3.1  在类的方法中,我们可以使用“this.属性”或“this.方法”的方式,调用当前对象属性或方法,但            是通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,            我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。

public void setRadius(double radius) {
		this.radius = radius;
	}
public girl{
    public int compare(Girl girl) {
		return this.age - girl.age;//this:当前对象的  girl:形参girl
}

   3.2  在类的构造器中,我们可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象属性或方法,但是通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时, 我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。

public Circle(double radius) {
		this.radius = radius;
	}

   3.3  this调用构造器

          A.  我们在类的构造器中,可以显式的使用“this(形参列表)”方式,调用本类中指定的其他                 构造器

          B.  构造器中不能通过"this(形参列表)"方式调用自己

          C.  如果一个类中有n个构造器,则最多有 n -1 构造器中使用了"this(形参列表)"

          D.  规定:"this(形参列表)"必须声明在当前构造器的首行

          E.  构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器

public Person(){//空参构造器
    this.eat();
}
public Person(String name){
    this();//调用上面的空参构造器
    this.name = name;
}
public Person(String name){
    this();//调用上面的空参构造器
    this.age = age;
}
public Person(String name,int age){
    this(age);//调用上面的带参构造器
    this.name = name;
}

4.什么时候使用this关键字呢?

   当在方法内需要用到调用该方法的对象时,就用this

   具体的:我们可以用this来区分局部变量和属性。

this.name = name;//对象.属性,所以第一个是属性

2.super(父类的)

2.1  super调用属性和方法

2.1.1  我们可以在子类的方法或构造器中,通过使用"super.属性"或"super.方法"的方式,显示的调用父类中声明的属性或方法,但是,通常情况下,我们习惯省略"super."

2.1.2  特殊情况,当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须是显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。

public class Person{
    int id = 1001;//身份证
}
public class Student extends Person{
    int id = 1002;//学生证
    public void Show(){
        System.out.println("id = " + id);//1001
        System.out.println("id = " + super.id);//1002调用父类属性id
    }
}

2.1.3  特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须是显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法

public class Person{
    public void eat(){
        System.out.println("人:吃饭");
    }
    public void walk(){
        System.out.println("人:走路");
    }
}
public class Student extends Person{
    @Override
    public void eat(){
        System.out.println("学生:多吃有营养的食物");
    }
}
public class SuperTest{
    public static void main(String[] args){
        Student s = new Student();
        s.eat();//学生:多吃有营养的食物
        super.eat();//人:吃饭
        this.walk();//子类没有重写父类的方法,先在子类中找,没找到,再去父类找
        super.walk();//直接去父类找
    }
} 

2.2  super调用构造器

2.2.1  我们可以在子列的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器

2.2.2  "super(形参列表)"的使用,必须声明在子类构造器的首行!

2.2.3  我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现

public class Person{
    public Person(String name,int age){
       this.name = name;
       this.age = age;
    }
}
public class Student extends Person{
     public Student(String name,int age){
        super(name);
        this.age = age;
    }
    public Student(String name,int age,String major){
        super(name,age);
        //this(name,age);//只能二选一
        this.major = major;
    }
}

2.2.4  在构造器的首行,没有显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器

public class Person{
    public Person(){
        System.out.println("我无处不在!");//证明调用了空参构造器
}
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
}
public class Student extends Person{
     public Student(String major){
        //super();//即使不写,默认调用此空参构造器
        this.major = major;
    }
}
public class SuperTest{
    public static void main(String[] args){
        Student s = new Student();
       //执行会输出:我无处不在!
    }
} 

2.2.5  在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)",调用父类中的构造器

2.2.6  在调用子类构造器之前,会先调用父类构造器,当子类构造器中没有使用"super(参数或无参数)"指定调用父类构造器时,是默认调用父类的无参构造器,如果父类中包含有参构造器,却没有无参构造器,则在子类构造器中一定要使用“super(参数)”指定调用父类的有参构造器,不然就会报错。

class Base{//此代码编译报错
    public Base(String s){
        System.out.print("B");
    }
}
public class Derived extends Base{
    public Derived (String s) {
        //super(s);//正确的代码应该有这个
        System.out.print("D");
    }
    public static void main(String[] args){
        new Derived("C");
    }
}

3.static(静态的)

1. static可以用来修饰:属性、方法、代码块、内部类

2. 使用static修饰属性:静态变量(或类变量

   2.1  属性:按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)

          实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。

          静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的

2.2 static修饰属性的其他说明:

   2.2.1 静态变量随着类的加载而加载,可以通过"类.静态变量"的方式进行调用

类名.方法()
public class InvokeMethod{
    public static void main(String[] args){
        InvokeMethod.t2();
    }
    public static void t2(){

    }
}

   2.2.2 静态变量的加载要早于对象的创建

   2.2.3 由于类只会加载一次,则静态变量在内存中也只会存在一份,存在方法区的静态域中

// static声明的属性被所有对象所共享
	private static int init = 1001;// 目前,内存当中只有唯一的一份init,
    private int init_ = 1002;//每个对象都有一份init_;

   2.2.4                             类变量                实例变量

                        类            yes                        no

                        对象        yes                        yes

3.使用static修饰方法:静态方法(不允许被重写!

        A.随着类的加载而加载,可以通过"类.静态方法"的方式进行调用

        B.                                        静态方法                非静态方法

                        类                        yes                          no

                        对象                     yes                         yes

        C.静态方法中,只能调用静态的方法或属性

            非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性

class Circle {
    private static int total;// 记录创建圆的个数
    public static int getTotal() {// 属性是static,则操作属性的方法也是static;
		return total;
	}
}

        静态属性举例:System.out;Math.PI;

4.static注意点:

   4.1 在静态的方法内,不能使用this关键字、super关键字

   4.2 关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。

   4.3 static家族可以互相访问

5.开发中,如何确定一个属性是否要声明为static的?

   > 属性是可以被多个对象所共享的,不会随着对象的不同而不同的

   > 类中的常量也常常声明为static

   开发中,如何确定一个方法是否要声明为static的?

   > 操作静态属性的方法,通常设置为static的

   > 工具类中的方法,习惯上声明为static的,比如:Math、Arrays、Collections

6.static代码块

用途:形成静态代码块以优化程序性能(由于它只会在类的加载时执行一次)

class Person{
    private Date birthDate;
    public Person(Date brithDate){
    this.birthDate = birthDate;
    }
    boolean isBornBoomer(){
        Date startDate = Date.valueOf("1946-1-1");
        Date endDate = Date.valueOf("1964-12-31");
        return brithDate.compareTo(startDate) >= 0 && brithDate.compareTo(endDate) < 0;
    }
}

isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和brithDate两个对象,造成了空间浪费 ,改成这样会更好:

class Person{
    private Date birthDate;
    private static Date startDate,endDate;
    static{
        Date startDate = Date.valueOf("1946-1-1");
        Date endDate = Date.valueOf("1964-12-31");
    }
    public Person(Date brithDate){
    this.birthDate = birthDate;
    }
    boolean isBornBoomer(){
        return brithDate.compareTo(startDate) >= 0 && brithDate.compareTo(endDate) < 0;
    }
}

7. static能作用于局部变量吗?

在Java中切记:static是不允许用来修饰局部变量。不为什么,这是Java语法的规定。

public void test(){
    static int a = 1;//会报异常
}

理由: (看到别人的好介绍)

A.局部变量最好不要设成静态变量,局部变量是有生命周期的,用完后JAVA很快就回收资源了;如果设成静态变量,那JAVA咋莫回收被其占用的内存

B.在方法里面定义的变量是局部变量,就是说他有一定的作用范围和生命周期,就只能在方法里面使用而不能将其扩展到别的地方,这个变量在方法结束后就会被回收器回收,就不再存在了 ,而你要强制将其加上static就是要把它的作用范围扩展到整个类,这就与你开始定义这个变量时违背了,这是语法上的错误

C.static变量是给类用的。这样类初始化的时候,就会给static进行初始化;如果你在方法里面定义一个static,这时候编译器就不知道你这个变量咋莫初始化了,这个是和java的设计相关的。java全是面向对象设计的,单独一个方法不能持有一块空间。

D.一个类中,一个static变量只会有一个内存空间,虽然有多个类实例,但这些类实例中的这个static变量会共享同一个内存空间,所以声明为static的变量实质上就是全局变量。所以static不能修饰局部变量。此外,局部变量是存放在栈中的,程序运行完立即释放,他只能在定义它的方法内部使用,所以不用static修饰符。

8.关于static修饰内部类在(JAVA类即成员那片博客里介绍了)

4.final(最终的


     1.final 可以用来修饰的结构:类、方法、变量
2.final 用来修饰一个类:此类不能被其它类所继承。
 比如:String类、System类、StringBuffer类(这些类的功能很全,基本不用再扩充)
3.final 用来修饰方法:表明此方法不可以被重写
 比如:Object类中getClass();
 4.final 用来修饰变量:此时的“变量”就称为是一个常量;常量建议大写,每个单词之间采用下划线连接
 4.1 final修饰属性:可以考虑赋值的位置有:显示初始化、代码块中初始化、构造器中初始化

注意:final修饰的实例变量,系统不负责赋默认值,要求程序员必须手动赋值;这个手动赋值,在变量后面可以,在代码块、构造器中也可以;但是final修饰的变量,系统不负责默认初始化赋值,方法中也不可以(因为在JVM加载过程中,构造器是加载的最后一道关卡,构造器调完对象就出生了若此时还未赋值,那就没意义了,方法加载的太晚)

class finalTest{
    final int WIDTH = 0;//显式初始化
    final int LEFT;
    final int RIGHT;
    {
    LEFT = 1;//代码块中初始化
    }
    public finalTest(){
        RIGHT = 2;//构造器中初始化
    }
    public finalTest(int n){
        RIGHT = n;//如果多个构造器构成重载,则每个构造器必须被赋值
    }
}


 4.2 final修饰局部变量:
 尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参,一旦赋值以后,就只能在方法体内使用此实参,但不能进行重新赋值。

class finalTest{
    public void show(){
        final int NUM = 10;//常量
        //NUM += 20;//错误,常量不能被操作
    }
    public void show(final int num){
         //num = 20;//错误,final修饰的形参只能被调用,不能被重新赋值
    }
}

 static final用来修饰属性:全局变量(接口中用的多)

public static final double PI = 3.1415926;

一道面试题: 

byte b1 = 1,b2 = 2,b3,b6,b8;
final byte b4 = 4,b5 = 6,b7 = 9;

b3 = b1 + b2;//A
b6 = b4 + b5;//B
b8 = b1 + b4;//C
b7 = b2 + b5;//D

只有B是对的
b1和b2是byte变量,在存储都会转为int
b3 = (byte)(b1 + b2);
final修饰的属性,不光值不能变,类型也不能变
final byte b4 = 4,b5 = 6,b7 = 9;//不会被编译器转为int

5.abstract(抽象的

abstract可以用来修饰的结构:类、方法 

1.abstract修饰类:抽象类

   1.1 此类不能被实例化

   1.2 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)

   1.3 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作

2.abstract修饰方法:抽象方法

    2.1 抽象方法只有方法的声明,没有方法体

public abstract void eat();//抽象方法

    2.2 包含抽象方法的类,一定是一个抽象类,反之,抽象类中可以没有抽象方法的

    2.3 若子类重写了父类中的所有的抽象方法后,此子类方可实例化

          若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修            饰

abstract使用上的注意点:

1.abstract不能用来修饰:属性、构造器等结构

2.abstract不能用来修饰私有方法(声明为private的方法不能被重写)、静态方法(不能被重写)、final的方法(不能被重写)、final的类

6.interface(接口)和implements

接口的使用(用于实现功能!!!!!!!!
 1.接口使用interface来定义
  2.Java中,接口和类是并列的两个结构
 3.如何定义接口:定义接口中的成员
    3.1 JDK7及以前,只能定义全局常量和抽象方法(不能定义变量)
          >全局常量:public static final的,但是书写时,可以省略不写(接口中的变量,本质上都是static的,而且是final类型的,不管你加不加static修饰)
          >抽象方法:public abstract的
    3.2JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法      

    // 静态方法
	public static void method1() {
		System.out.println("CompareA:北京");
	}
	// 默认方法
	public default void method2() {
		System.out.println("CompareA:上海");
	}


 4.接口中不能定义构造器!意味着接口不可以实例化。
 5.Java开发中,接口通过让类去实现(implements)的方式来使用。
    如果实现类覆盖率接口中的所有抽象方法,则此实现类就可以实例化。
    如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类;即接口的实现类必须      实现接口的全部方法
 6.Java类可以实现多个接口--->弥补了Java单继承性的局限性
    格式:class AA extends BB implements CC,DD,EE
 7.接口与接口之间可以继承(通过extends),而且可以多继承
 8.接口的具体使用,体现多态性(这里详细介绍了关于创建接口匿名实现类的对象)

public class USBTest {
	public static void main(String[] args) {
		Computer com = new Computer();
		//1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();//接口USB不能造对象,只能造实现类的对象,多态性的体现
		com.transferData(flash);
		//2.创建了接口的非匿名实现类的匿名对象
		com.transferData(new Printer());
		//3.创建了接口的匿名实现类的非匿名对象
		USB phone = new USB() {
			@Override
			public void start() {
				System.out.println("手机开始工作");
			}
			@Override
			public void stop() {
				System.out.println("手机结束工作");
			}
		};
		com.transferData(phone);
		//4.创建了接口的匿名实现类的匿名对象
		com.transferData(new USB() {
			@Override
			public void start() {
				System.out.println("mp3开始工作");
			}
			@Override
			public void stop() {
				System.out.println("mp3结束工作");
			}
		});
	}
}
interface USB{
	//常量:定义了长、宽、最大最小的传输速度等
	void start();
	void stop();
}
class Computer{
	public void transferData(USB usb) {
		usb.start();//执行结果:U盘开启工作
		System.out.println("具体传输数据的细节");
		usb.stop();//执行结果:U盘结束工作
	}
}
class Flash implements USB{
	@Override
	public void start() {
		System.out.println("U盘开启工作");
	}
	@Override
	public void stop() {
		System.out.println("U盘结束工作");	
	}
}
class Printer implements USB{
	@Override
	public void start() {
		System.out.println("打印机开启工作");
	}
	@Override
	public void stop() {
		System.out.println("打印机结束工作");	
	}
}

9.接口,实际上可以看作是一种规范
 接口的使用
1.接口使用上也满足多态性
2.接口,实际上就是定义了一种规范

接口中只有public权限,接口中只有全局常量和抽象方法

只有在接口中abstract static final public 都可以省略掉!!!(阿里规约中,定义接口,尽量简洁!)

public interface IMessage{
    //全局常量
    int NUM = 100;
    //抽象方法
    String msg();
}

 3.开发中,体会面向接口编程!

java8关于接口的5个新规范

public class SubClassTest {
	public static void main(String[] args) {
		SubClass s = new SubClass();
		// 知识点1:接口中定义的静态方法,只能通过接口来调用。
		CompareA.method1();
		// 知识点2:通过实现类的对象,可以调用接口中的默认方法。
		// 如果实现类重写了接口中的默认方法,调用时,仍然用的是重写以后的方法
		s.method2();
		// 知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法。
		// 那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则
		// 知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法。
		// 那么在实现类没有重写此方法的情况下,报错:---->接口冲突。
		// 那就需要我们必须在实现类中重写此方法
		// 5在下面
		s.method3();
	}
}
public interface CompareA {
	// 静态方法
	public static void method1() {
		System.out.println("CompareA:北京");
	}
	// 默认方法
	public default void method2() {
		System.out.println("CompareA:上海");
	}
	default void method3() {
		System.out.println("CompareA :上海");
	}
}
public interface CompareB {
	default void method3() {
		System.out.println("CompareB:上海");
	}
}
class SubClass extends SuperClass implements CompareA, CompareB {
	@Override
	public void method2() {
		System.out.println("SubClass:上海");
	}
	@Override
	public void method3() {
		System.out.println("SubClass:深圳");
	}
	// 知识点5:如何在子类(或实现类)的方法中调用父类,接口中被重写的方法
	public void myMethod() {
		method3();// 调用自己定义的重写的方法
		super.method3();// 调用的是父类中声明的
		// 调用接口中的默认方法
		CompareA.super.method3();
		CompareB.super.method3();
	}
}

接口仍然不能直接实例化对象,必须通过子接口来向上转型。

public class MessageImpl immplements IMessage,INews{
    @Override
    public String msg(){
        return "hello bit";
    }
    @Override
    public void getNews(){
        System.out.println("hello news~");
    }
    public static void main(String[] args){
        IMessage message = new MessageImpl();
        System.out.println(message.msg());
    }
}

message只能调用msg方法

不能调用getNews - (INews接口定义)

要想使用getNews方法,就需要父接口间的相互转换。

INews news = (INews)message;
public static void main(String[] args){
    IMessage message = new MessageImpl();
    System.out.println(message.msg());
    INews news = (INews)message;
    news.getNews();
}

父类/父接口 父引用 = new 子类实例();

到底能调用啥方法,看前面父类/父接口中定义了啥方法

调用方法长啥样子,要看new的是那个子类。

接口的使用者与实现者

电脑是USB接口的使用者而非实现者(类的内部拥有USB接口,USB的实现者)

关于接口的一种规约:(个人感觉没人用)

一般接口的命名使用I开头和类做区分

子类实现接口可以使用impl结尾,表示是接口的子类。

//interface定义了IMessage
public interface IMessage{
    //全局常量
    public static final int NUM = 100;
    //抽象方法
    public String msg();
}
public class MessageImpl implements IMessage{
    @Override
    public String msg() {
        return "hello bit";
    }
}

7.instanceof(也可实现接口)

背景:有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能调用。 

开发中主要用向上转型(多态)

 如何才能调用子类特有的属性和方法?

答:向下转型,使用强制类型转换符。


        Man m1 = (Man)p2;
        m1.earnMoney();
        //使用强转时,可能出现ClassCastException的异常
        Woman w1 = (Woman)p2;//p2是Man;两者并列关系
        w1.goShopping();

instanceof关键字的使用

a instanceof A: 判断对象a是否是类A的实例;如果是,返回true,如果不是,返回false.

使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型,如果返回false,不进行向下转型。

如果 a instanceof A 返回true,则 a instanceof B也返回true.

其中,类B时类A的子类。

Person p2 = new Man();
if(p2 instanceof Woman){//Woman和Man无关系,不会输出
    Woman w1 = (Woman)p2;
    w1.goShopping();
    system.out.println("********Woman***********");
}
if(p2 instanceof Woman){//满足子父类关系,可以输出
    Woman m2 = (Woman)p2;
    m2.earnMoney();
    system.out.println("********Man***********");
}
if(p2 instanceof Person){//满足子父类关系,可以输出
    system.out.println("********Person***********");
}
if(p2 instanceof Object){//满足子父类关系,可以输出
    system.out.println("********Object***********");
}

向下转型中的几个常见问题:

//问题一:编译时通过,运行时不通过//这种情况就要加instanceof判断
//情况A:
Person p3 = new Woman();
Man m3 = (Man)p3;
//情况B:
Person p4 = new Person();
Man m4 = (Man)p4;//不能强转为其子类
//问题二:编译通过,运行也通过
Object obj = new Woman();
Person p = (Person)obj;//开发中可以这样
//问题三:编译不通过
Man m5 = new Woman();//报错原因:类型不匹配
//这种方式可以骗过编译器,让其编译时通过,但运行时,报错:类型不匹配
Object o = new Woman();
Man m6 = (Man)o;

向上转型(多态)和向下 转型的总结:

向上转型:参数统一化,使用父类引用,无论是那个子类,都能调用父类中已经定义好的方法,具体表现为啥样,就看子类方法覆写的内容了 => 对象的多态性

运行时多态性体现:

向上转型是在子类和父类间天然发生的is a关系:Dog is an Animal

能调用的方法要看父类,此时引用是父类的引用,只有在父类中定义了相关方法才能使用

到底调用的是谁要看子类是否覆写,若子类覆写了这个方法,则调用的一定是子类覆写后的方法

向下转型

Student stu = (Student)o;

若此时要调用只有Student(子类)类中才具备的方法或属性时,就需要向下转型,将父类引用的外衣脱掉,还原为子类引用。

此时是进行Student对象的比较,比较Student类中的name和age属性,这俩属性是Student独有的,就需要向下转型还原为Student引用

看到的好的解释的博客(不一定正确,但思想可以):当一个类继承了另一个类,子类中没有父类的方法时。用子类的对象调用方法时,会首先在子类中查找,如果子类中没有该方法,再到父类中查找。

当一个方法只在父类中定义时,调用该方法时会使用父类中的属性。

如果该方法中又调用了其他方法,那么还是按照之前的顺序,先在子类中查找,再在父类中查找。

8.import(导包)

1.在源文件中显式的使用import机构导入制定包下的类、接口

2.生命在包的声明和类的声明之间

3.如果需要导入多个结构,则并列写出即可

4.可以使用"xxx.*"的方式,表示可以导入xxx包下所有的结构

5.如果使用的类或接口是java.lang包下定义的,则可以省略import结构

6.如果使用的类或接口是本包下定义的,则可以省略import结构

7.如果在源文件中,使用了不同剥下的同名的类,则必须至少有一个类需要以全类名的方式显示。

8.使用"xxx.*"的方式表明可以调用xxx包下的所有的结构,但是如果使用的是xxx子包下的结构,则仍需显式导入

9.import static:导入指定类或接口中的静态结构:属性或方法。

补充:

1.(abstract不能与static关键字共存)abstract不能被static修饰,因为抽象方法要被重写、而static和子类占不到边。反过来也一样static方法一定不能被abstract方法修饰,static不属于对象而属于类,static方法可以被类直接调用(抽象方法需要被实现才能被调用,也就是重写其方法),这样注定了static方法一定有方法体,不能是没有方法体的抽象方法

2.abstract不能与final关键字共存,因为final关键字修饰的类是不能被继承的。

3.

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值