【java】this/super/abstract/final/static/private关键字汇总

目录

1 this关键字

2 super关键字

3 abstract关键字

3.1 abstract关键字使用 Eclipse操作引导

  3.2 abstract使用方法总结

4 final关键字

4.1 小总结:

4.2 final面试题

5.static关键字

5.1 关于静态资源

5.2 静态方法/非静态方法/静态资源?

5.3 静态块

5.3.1静态资源加载顺序

5.3.2 静态变量

5.3.3 父类、子类静态代码块

5.4 static修饰类

6  public/private/protected/default四种修饰符的具体区别

7 private关键字 --面向对象封装


1 this关键字

  • this关键字表示调用当前方法的类对象本身,哪一个类对象调用该方法,this 就表示哪个对象

 

2 super关键字

  • 指明调用的是父类的成员变量和成员方法
  • 区分子类和父类同名的内容
package com.qfedu.a_extends;

class Person {
	public String name;
	public int age = 10;
	
	public void work() {
		System.out.println("Person类work方法");
	}
}

/**
 * super关键字区分父类和子类同名内容
 * @author Anonymous
 *
 */
class SinglePerson extends Person {
	public int age = 20;
	
	public void work() {
		System.out.println("SinglePerson类work方法");
	}
	
	/*
	 * super关键字可以解决父类和子类同名内容情况。
	 */
	public void test() {
		// 子类和父类有同名内容情况下,默认为就近原则
		System.out.println(age);
		
		// 通过super明确告知编译器,这里使用的age是父类成员变量age
		System.out.println(super.age);
		
		// 调用方法也是采用就近原则
		work();
		
		// 通过super明确告知编译器这里调用的是父类的work方法。
		super.work();
	}
}

public class Demo3 {
	public static void main(String[] args) {
		
	}
}

3 abstract关键字

abstract修饰的方法   要求子类必须强制完成/强制重写!!

3.1 abstract关键字使用 Eclipse操作引导

第一个问题:
    Abstract methods do not specify a body
    abstract修饰的方法,不允许有方法体

快速修复:
    Ctrl + 1
    Remove method body;
    删除当前abstract修饰方法的方法体。

 第二个问题:
     The abstract method Q in type LOLHero can only be defined by an abstract class
         在LOLHero类内abstract修饰的方法q,有且只能定义在abstract修饰的类内
     The type LOLHero must be an abstract class to define abstract methods
         LOLHero类必须是一个abstract修饰的类,才可以定义abstract修饰的方法
 
 快速修复:
     Ctrl + 1
     Make type 'LOLHero' abstract
     
 第三个问题:

     The type HappyWindBoy must implement the inherited abstract method LOLHero.Q()
        HappyWindBoy类因为继承LOLHero类,必须实现LOLHero类内的abstract修饰的方法 Q();
 快速修复:
      Ctrl + 1
      Add unimplemented method;
          添加未实现的方法


  3.2 abstract使用方法总结

  •  abstract关键字目前只要求了解语法规范。【实际使用和开发使用,后期项目中讲解】
  •  abstract修饰的方法不能有方法体,有且只有方法的声明,这里只是在当前类内告知编译器,这里定义了一个方法的声明。
  • abstract修饰的方法,有且只能存在于abstract修饰的类内,或者interface接口内
  • 一个普通类如果继承abstract修饰的类需要完成abstract类内的所有abstract修饰方法【语法强制要求】
  • abstract修饰的类请问有没有类对象???
  • abstract修饰的类不能创建自己的类对象,因为abstrat修饰的类内可能存在abstract修饰的方法,而abstract修饰的方法没有方法体,无法通过类对象调用执行。

4 final关键字

  • 用来修饰数据,包括成员变量和局部变量,该变量只能被赋值一次且它的值无法被改变。对于成员变量来讲,我们必须在声明时或者构造方法中对它赋值;
  • 用来修饰方法参数,表示在变量的生存期中它的值不能被改变
  • 修饰方法,表示该方法无法被重写
  • 修饰,表示该类无法被继承

4.1 小总结:

  • 成员变量

    final修饰的成员变量,定义时必须初始化,并且无法被重新赋值。

  • 成员方法

    final修饰的成员方法,不能被子类重写,为最终方法。

  • 局部变量

    final修饰的局部变量一旦被赋值无法修改!!!

    final修饰的类不能被子类继承,没有子类
    断子绝孙

  • 代表之作:

        Java中的String字符串类就是一个final修饰的类

4.2 final面试题

package com.qfedu.d_final;

class Person {
	public String name = "苟磊";
	public int age = 16;
}

public class Demo2 {
	public static void main(String[] args) {
		final Person person = new Person();
		
		System.out.println(person.name + " " + person.age);
		
		/*
		 * 一下操作那些正确,那些错误?
		 * 
		 * 请问:
		 * 		这里是指向不可变,还是指向内容不可变???
		 * 
		 * 这里final Person person 实际上修饰的内容是person引用数据类型变量
		 * 也就是说当前引用数据类型变量中保存的数据是不能修改的!!!
		 * 引用数据类型变量保存的数据是地址,地址指向不得改变。
		 * 
		 * 指向空间中保存的数据内容是可以改变的!!!
		 * 
		 * 生活例子:
		 * 		你买的房子地址不会发生改变,但是房子内部的装修装饰是可以发生改变。
		 */
		 // person = new Person();
		 
		 person.name = "航海中路彭于晏";
		 person.age = 6;
	}
}

5.static关键字

static关键字最基本的用法是:

1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来

2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来

 

5.1 关于静态资源

被static修饰的变量、被static修饰的方法统一属于类的静态资源,是类实例之间共享的,换言之,一处变、处处变。JDK把不同的静态资源放在了不同的类中而不把所有静态资源放在一个类里面,很多人可能想当然认为当然要这么做,但是是否想过为什么要这么做呢?个人认为主要有三个好处:

1、不同的类有自己的静态资源,这可以实现静态资源分类。比如和数学相关的静态资源放在java.lang.Math中,和日历相关的静态资源放在java.util.Calendar中,这样就很清晰了

2、避免重名。不同的类之间有重名的静态变量名、静态方法名也是很正常的,如果所有的都放在一起不可避免的一个问题就是名字重复,这时候怎么办?分类放置就好了。

3、避免静态资源类无限膨胀,这很好理解。

 

5.2 静态方法/非静态方法/静态资源?

public class A
{
    private int i = 1;

    public static void main(String[] args)
    {
        i = 1;
    }
}

当然有错,在第7行的地方。不妨这么思考这个问题:

静态资源属于类,但是是独立于类存在的。从JVM的类加载机制的角度讲,静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的。类的初始化早于类的new,比如Class.forName(“xxx”)方法,就是初始化了一个类,但是并没有new它,只是加载这个类的静态资源罢了。所以对于静态资源来说,它是不可能知道一个类中有哪些非静态资源的;但是对于非静态资源来说就不一样了,由于它是new出来之后产生的,因此属于类的这些东西它都能认识。所以下面的几个问题答案就很明确了:

  • 静态方法能不能引用非静态资源?

       不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。

  • 静态方法里面能不能引用静态资源?

      可以,因为都是类初始化的时候加载的,大家相互都认识。

  • 非静态方法里面能不能引用静态资源? 

      可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识

 

5.3 静态块

静态块也是static的重要应用之一。也是用于初始化一个类的时候做操作用的,和静态变量、静态方法一样,静态块里面的代码只执行一次,且只在初始化类的时候执行。静态块很简单,不过提三个小细节:

5.3.1静态资源加载顺序

public class A
{
    private static int a = B();

    static
    {
        System.out.println("Enter A.static block");
    }

    public static void main(String[] args)
    {
        new A();
    }

    public static int B()
    {
        System.out.println("Enter A.B()");
        return 1;
    }
}

打印结果是:

Enter A.B()
Enter A.static block

得出第一个结论:

静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。这和周志明老师《深入理解Java虚拟机:JVM高级特性与最佳实践》中类初始化中的说法“()方法是由编译器自动收集类中所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的”是一致的。

5.3.2 静态变量

再看一个例子:

public class A
{
    static
    {
        c = 3;
        System.out.println(c);
    }

    private static int c;
}

这段代码的  "   System.out.println(c);  "  是有错误的“Cannot reference a field before it is defined”。

从这个例子得出第二个结论:

静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问

5.3.3 父类、子类静态代码块

最后一个小例子:

public class A
{
    static
    {
        System.out.println("A.static block");
    }

    public A()
    {
        System.out.println("A.constructor()");
    }
}


public class B extends A
{
    static
    {
        System.out.println("B.static block");
    }

    public B()
    {
        System.out.println("B.constructor()");
    }

    public static void main(String[] args)
    {
        new B();
        new B();
    }
}

运行结果:

A.static block
B.static block
A.constructor()
B.constructor()
A.constructor()
B.constructor()
这个例子得出第三个结论:

静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。

 

5.4 static修饰类

这个用得相对比前面的用法少多了,static一般情况下来说是不可以修饰类的,如果static要修饰一个类,说明这个类是一个静态内部类(注意static只能修饰一个内部类),也就是匿名内部类。像线程池ThreadPoolExecutor中的四种拒绝机制CallerRunsPolicy、AbortPolicy、DiscardPolicy、DiscardOldestPolicy就是静态内部类。静态内部类相关内容会在写内部类的时候专门讲到。

import static

这个比较冷门,基本很少看见有地方用,使用JUnit可能会用到,写assert的时候会方便些。import static是JDK1.5之后的新特性,这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名.资源名,可以直接使用资源名。注意一下,import static必须这么写,而不能写成static import。举个例子来看一下:

import static java.lang.Math.*;

public class A
{
    public static void main(String[] args)
    {
        System.out.println(sin(2.2));
    }
}

这么写意味着我导入了Math下的所有静态资源,main函数里面我就可以直接用sin(2.2)而不需要使用Math.sin(2.2)了。注意一下,要写import static java.lang.Math.*,最后的“.*”不可少,有了这两个字符才意味着导入的是Math下的所有静态资源,写成import static java.lang.Math是有问题的。当然,我们也可以指定只导入某个静态资源,比如只导入Math下sin这个方法而不导入Math下的所有静态资源:

import static java.lang.Math.sin;

public class A
{
    public static void main(String[] args)
    {
        System.out.println(sin(2.2));
    }
}

这么写也是没问题的。导入静态变量也是一样,有兴趣的可以自己试一下。对于import static,个人的态度是:

1、简化了一些操作,比如静态导入Math下的所有静态资源,在频繁使用Math类下静态资源的地方,可以少些很多“Math.”

2、降低了代码的可读性

建议在某些场景下导入特定的静态资源,不建议使用“.*”的导入方式。

 

6  public/private/protected/default四种修饰符的具体区别

https://blog.csdn.net/qq1437722579/article/details/97948706

7 private关键字 --面向对象封装

权限修饰符
    private
        私有化,私有修饰
        private修饰的成员变量,成员方法和构造方法有且只能当前类内使用。
        private修饰成员变量,可以保证数据操作统一性,和数据操作安全性
        private修饰成员方法,可以保证私密性方法运行,类外无法执行操作
        private修饰构造方法,限制构造方法使用,后期用于【单例模式】
    public
        公开的,所修饰的成员变量,成员方法和构造方法,都是可以直接类外使用。
       

在JavaBeans规范中,要求成员变量全部【private修饰】

private修饰成员变量类外无法操作,需要提供对应的Setter和Getter方法。

Setter方法格式
	public void set成员变量名(对于成员变量数据类型参数) {
		赋值语句
	}
	Person ==> String name;
	
	public void setName(String name) {
		this.name = name;
	}
	
Getter方法格式:
	public 对于成员变量数据类型返回值 get成员变量() {
		return 成员变量;
	}
	Person ==> String name;
	
	public String getName() {
		return name;
	}
	特殊情况:
		如果成员变量数据类型是boolean, 对应get方法
		Person ==> boolean married;
		
		这里要求is开头
		public boolean isMarried() {
			return married;
		}
public class Cat {
    private String name;
    private String color;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 

你可能感兴趣的:(java入门)