Java面向对象--关键字(super、static、final)
Java关键字是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量。Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数。本篇博客介绍super、static和final关键字的具体用法。
目录:
☍ super关键字
super关键字的使用
在Java类中使用super来调用父类中的指定操作:
☃ super可用于访问父类中定义的属性
☃ super可用于调用父类中定义的成员方法
☃ super可用于在子类构造器中调用父类的构造器
super.变量名; //调用父类属性
super.方法名(参数列表); //调用父类方法
super(参数列表); 在构造器中调用父类构造器
✦ 如果子类和父类没有同名成员,使用时可以省略super
注意:
➥ 尤其当子父类出现同名成员(同名属性和方法)时,可以用super表明调用的是父类中的成员
➥ super的追溯不仅限于直接父类,还包括间接父类(父类的父类...)
➥ super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
✦ 使用this访问属性和方法时,如果在本类中未找到,会从父类中查找,super则是直接从父类中寻找
✦ 总结而言this和super主要就是解决成员重名问题,若不重名使用时都可以省略
super关键字调用父类的构造器
☃ 子类中所有的构造器默认都会访问父类中空参的构造器
☃ 当父类中没有空参数的构造器时,子类的构造器必须通过this(参 参
表 数列表)或者super( 参数列表)语句指定调用本类或者父类中相应的
构造器。并且this()和super()只能在构造器中出现一个,且必须放在构造器的首行
☃ 如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错
public class Person{
private String name;
private int age;
public Person(String name){
this.name = name;
}
public Person(String name, int age){
this(name);
this.age = age;
}
}
public class Student extends Person{
private char sex;
public Student(String name,int age,char sex){
super(name,age);
this.sex = sex;
}
public Student(String name,char sex){
super(name);
this.sex = sex;
}
public Student(String sex){
// this.sex = sex; 编译出错,父类没有空参构造函数super();
}
}
this和super的区别
区别 | this/this(参数列表) | super/super(参数列表) | |
---|---|---|---|
1 | 访问属性 | 访问本类中的属性,如果本类没有此属性则从父类中继续查找 | 直接访问父类中的属性 |
2 | 调用访问 | 访问本类中的方法,如果本类没有此方法则从父类中继续查找 | 直接访问父类中的方法 |
3 | 调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
☍ static关键字(重点)
static关键字概述
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有中国人对象都拥有一个国籍‘中国’,这个属性不必在声明中国人对象像时去为每一个对象都单独分配一个用于代表国家名称的变量。
static关键字声明的属性和方法是静态变量和静态方法,或者称为类属性和类方法,是作用于全局的,声明为static的属性和方法在内存中是唯一的,任何该类对象对类属性和方法的修改都会影响其他对象的调用结果。
static属性和方法的设计思想
☃ 类属性作为该类各个对象之间共享的变量。在设计类时,分析 哪
些属性 不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。
☃ 如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。
static关键字的使用和特点
☃ 在Java类中,可用static修饰成员变量、方法、代码块、内部类
特点:
➥ 随着类的加载而加载,优先于对象存在
➥ 修饰的成员,被所有对象所共享
➥ 访问权限允许时,可不创建对象,直接被类调用
➥ 由于类只会加载一次,所以静态成员在内存中也只会存在一个。存在方法区的静态域中
静态变量和静态方法
☃ 静态变量由该类的所有实例共享 ,没有对象的实例时,可以通过“类.静态变量”的方式调用
☃ 没有对象的实例时,可以用“类名.方法名()”的形式访问由static修饰的类方法
例子:
public class StaticTest {
/*
* static关键字
* 1、static:静态的,类的
* 2、static可以用来修饰属性,方法,代码块,内部类
* 3、static静态变量(类属性)
* 3-1、属性:按是否使用了static修饰,分为静态属性 vs 非静态属性(实列变量)
* 实例变量:我们创建了类的多个独享,每个独享都独立拥有类中的非静态属性,当修改其中一个对象中的非静态属性时,
* 不会导致其他对象中同样的属性值的改变
* 静态变量:我们创建子类的多个对象,多个对象共享同一个静态变量,当通过某一个都对象修改静态变量时,
* 会导致其他对象调用此惊天变量时,是调用修改过的变量
* 3-2、static修饰的其他说明
* (1)、静态变量随着类的加载而加载
* (2)、静态比变量的加载早于都对象的创建,可以通过类.静态变量的方式调用
* (3)、由于类只会加载一次,所以静态变量在内存中也只会存在一个。存在方法去的静态域中
* 4、static静态方法(类方法)
* 4-1、随着类的加载而加载,可以通过‘类.静态方法()’的方式调用
* 4-2、静态方法中,只能调用静态的成员
* 非静态方法中,能调用静态和非静态的成员
*
* 注意:
* 1、在静态的方法中,不能使用this和supper关键字
* 2、不能重写静态方法
*
* 开发中什么时候使用
* 1、属性可以被多个对象共享,不会随着对象的不同而不同
* 2、开发中,操作静态属性的方法通常设置为static方法
* 3、工具类中的方法,习惯声明为static的,比如:Math、Arrays、Collections
*/
static double PI = 3.14;
static int distance;
char nuit;
public static void main(String[] args) {
Chinese c1 = new Chinese();
c1.name = "张三";
c1.age = 30;
Chinese c2 = new Chinese();
c2.name = "李四";
c2.age = 30;
c1.nation = "CHN";
System.out.println(c2.name + "国籍:" + c2.nation);
// 本类中不用创建对象就可以访问静态成员
System.out.println("PI:" + PI);
run();
//调用其他类的静态变量和静态方法
System.out.println(Chinese.nation);
Chinese.eat();
}
public static void run() {
//nuit = '米'; 错误,在static 方法内部只能访问类的 的static修饰的属性或方法
//this.distance = 3000;tatic方法中不能有this和supper
distance = 1000;
System.out.println("跑了:" + distance);
}
}
class Chinese{
String name;
int age;
static String nation;
public static void eat() {
System.out.println("吃饭");
}
}
注意:
➥ 在static方法内部只能访问类的的static修饰的属性或方法,不能访问类的非static的结构
➥ 因为不需要实例就可以访问static 方法,因此static 方法内部不能有this和supper
➥ static 修饰的方法不能被重写
☍ final关键字
final关键字的使用
在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。
☃ final标记的类不能被继承。提高安全性,提高程序的可读性。
☄ 例如:String类、System类、StringBuffer类
☃ final 标记的方法不能被子类重写
☄ 例如:Object类中的getClass()方法
☃ final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次,赋值后不可在其他类和方法中更改。
☄ final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋值,然后才能使用。
☄ 例如:Math中的PI(public static final double PI = 3.14159265358979323846;)
/*final:最终的
* 1、final可以用来修饰的结构:类、方法和变量
* 2、final用来修饰类:final类不能被其他类继承,比如String类,System类,Buffer类
* 3、final用来修饰方法:不能被子类重写,如:Object类中的getClass()方法
* 4、final用来修饰变量,此时的变量称为常量
* 4-1、final可以赋值的位置:显示初始化,代码块中初始化,构造器中初始化(声明的每个构造器中都要初始化final属性)
* 4-2、final修饰形参时,表明形参是一个常量,当我们在调用方法时赋值后,在方法体内能使用该形参,但不可修改
*
* static final 修饰属性:全局常量
* static final 修饰方法:全局方法
*/
public class finalDemo {
//必须要给final变量赋值,赋值后不可再修改
//final int MAX; 错误
final double R = 1.314; //显示赋值
final double PI;
final String NATION;
{ //代码块赋值
NATION = "China";
}
public finalDemo() {
PI = 3.1415926; //构造器赋值
}
public finalDemo(int n) {
PI = n; //此处还需初始化,因为PI为常量,在调用重载构造器时,系统不确定是否给PI赋过值适合不同对象又不同的final属性
//this.R = n; 不可以使用this.fianl属性的方式初始化,
//因为this指向当前对象,一旦对象创建,fianl属性的值也应当已经确定,不可再修改
}
public void setPI() {
//this.PI = 3.14; 不可以修饰final属性的值
}
//fianl常量形参
public void setNum(final int num) {
//num = 32; 错误,不可修改
System.out.println("num:" + num);
}
}
final class FinalA{
}
/*final类不能被继承
class B extends FinalA{
}*/
class A{
final public void shout() {
System.out.println("hello world");
}
}
class B extends A{
/*不能重写final方法
* public void shout() {
System.out.println("hello China");
}*/
}
本博客与CSDN博客༺ཌ༈君☠纤༈ད༻同步发布