04java基础课堂笔记 - 面向对象课时2-关键字super this instanceof static final

p69 super详解

1.1 this和super
  - super不是引用,也不保存内存地址,super也不指向任何对象
  - super只代表当前对象内部的那一块父类型的特征
  - this代表当前对象,可以独立使用被直接调用,而super不支持单独使用,后面必须有点

1.2、super() 表示通过子类的构造方法调用父类的构造方法,模拟现实世界的这种场景:要想有儿子,需要先有父亲
  - 在子类所有的构造方法中都有一个隐藏代码“super(); ”,默认调用父类的无参构造,因此建议显示定义父类的无参构造,保证父类的无参构造存在
  - 也可以显示编辑“super(实参)”语句,调用父类的有参构造
  - this()和super()不能共存,因为它们都必须是构造方法的第一行
  - 子类构造方法执行时必然调用父类构造方法,但无论new什么对象,父类的构造方法一定会执行,最后老祖宗类Object类的无参构造方法一定会执行,而且Object类的无参构造处于栈顶,最后调用最先执行结束

2.1、super可以用在实例方法中和构造方法中
  - super语法是“super.”、“super()”
  - super不能使用在静态方法中
  - super.大部分情况下可以省略,什么时候不能省略呢?
  - super()这种语法只能出现在构造方法的第一行,表示在子类的构造方法中调用“父类”中的构造方法,目的是创建子类对象时,先初始化父类型特征

2.2、访问父类特征的数据的语法:

    super. 属性名
    super. 方法名(实参列表);

2.3、用在构造方法中调用父类的构造方法:

    super();
    super(实参列表);

2.4、super.大部分情况下可以省略,什么时候不能省略呢?
  当子类和父类中有同名属性,或者有相同的方法(方法覆盖)时,如果想在子类中访问父类特征的数据,那么必须使用“super.”加以区分
  java允许在子类中出现父类的同名变量/同名方法,那么怎么区分呢?
  this.name 访问当前对象的name属性
  super.name 访问当前对象的父类特征中的name属性
  this.move(); 访问当前对象的move()方法,重写的方法
  super.move(); 访问父类中的move()方法

4.1、注意:

  在构造方法执行过程中,一连串的调用了父类的构造方法,父类的构造方法又继续向上调用它的父类的构造方法,但是实际上只创建了一个对象
4.2、思考:super(实参)真是的作用是什么?
  初始化当前对象的父类型特征,并不是创建新对象,实际上对象只创建了一个
4.3、super的真正意义是什么?
  super关键字代表的是当前对象的那部分父类型特征

示例1:super()的作用

public class Test{
    public static void main(String[] args){
        //1 4 3
        new B();
    }
}

class A extends Object{
    public A(){
        //默认代码,调用父类的构造方法
        //super();
        System.out.println("1 A类的无参构造方法!");
    }
    public A(int i){
        //super();
        System.out.println("2 A类的有参构造方法!");
    }
}
class B extends A{
    public B(){
        //使用this()调用当前类的有参构造,此时super()消失
        this("zhangsan");
        System.out.println("3 B类的无参构造方法!");
    }
    public B(String name){
        //super();
        System.out.println("4 B类的有参构造方法!");
    }
}
View Code

示例2:判断程序的输出结果

public class Test{
    public static void main(String[] args){
        //1 3 7 6 5
        new C();
    }
}

class A extends Object{
    public A(){
        System.out.println("1-A类的无参构造执行!");
    }
    public A(int i){
        System.out.println("2-A类的有参构造执行!");
    }
}
class B extends A{
    public B(){
        System.out.println("3-B类的无参构造执行!");
    }
    public B(String name){
        System.out.println("4-B类的有参构造执行(String)");
    }
}
class C extends B{
    public C(){
        this("zhangsan");
        System.out.println("5-C类的无参构造执行!");
    }
    public C(String name){
        this("zhangsan",20);
        System.out.println("6-C类的有参构造执行(String)");
    }
    public C(String name,int age){
        System.out.println("7-C类的有参构造执行(String,int)");
    }
}
View Code

 

示例3:在恰当的时间使用:super(实参列表)

public class Test{
    public static void main(String[] args){
        CreditAccount ca1 = new CreditAccount();
        System.out.println(ca1.getActno() + "," + ca1.getBalance() + "," + ca1.getCredit());
        
        CreditAccount ca2 = new CreditAccount("11111",10000.0,0.999);
        System.out.println(ca2.getActno() + "," + ca2.getBalance() + "," + ca2.getCredit());
    }
}
//账户
class Account extends Object{
    private String actno;
    private double balance;
    public Account(){
        //super();
        //this.actno = null;
        //this.balance = 0.0;
    }
    public Account(String actno,double balance){
        this.actno = actno;
        this.balance = balance;
    }
    //get/set
    public void setActno(String actno){
        this.actno = actno;
    }
    public String getActno(){
        return actno;
    }
    public void setBalance(double balance){
        this.balance = balance;
    }
    public double getBalance(){
        return balance;
    }
}
//信用卡
class CreditAccount extends Account{
    private double credit;
    public CreditAccount(){
        //super();
        //this.credit = 0.0;
    }
    public CreditAccount(String actno,double balance,double credit){
        /*私有属性只能在本类中访问
        this.actno = actno;
        this.balance = balance;
        */
        //以上两行代码在恰当的位置,正好可以使用:super(actno,balance);
        //通过子类的构造方法调用父类的构造方法
        super(actno,balance);
        this.credit = credit;
    }
    
    public void setCredit(double credit){
        this.credit = credit;
    }
    public double getCredit(){
        return credit;
    }
}
View Code

 示例4:super()  ruper.  this.的使用以及不能省略情况

public class Test{
    public static void main(String[] args){
        Vip v = new Vip("张三");
        v.shopping();
    }
}
//客户
class Customer{
    String name;
    public Customer(){}
    public Customer(String name){
        super();
        this.name = name;
    }
}

class Vip extends Customer{
    //重定义属性代表子类的独立特征
    //String name;
    public Vip(){}
    public Vip(String name){
        //调用父类的有参构造
        super(name);
    }
    
    public void shopping(){
        System.out.println(this.name + "正在购物!");
        //super.表示当前对象的父类特征,是当前对象中的一块空间
        System.out.println(super.name + "正在购物!");
        System.out.println(name + "正在购物!");
    }
}
View Code

 

示例5:super不是引用

/*测试结论:
    super不是引用,也不保存内存地址,super也不指向任何对象
    super只代表当前对象内部的那一块父类型的特征
*/
public class Test{
    public static void main(String[] args){
        Test t = new Test();
        t.dosome();
    }
    
    public void dosome(){
        //输出“引用”的时候,会自动调用引用的toString()方法
        //System.out.println(this.toString());
        System.out.println(this);
        
        //编译错误,需要‘.’
        //System.out.println(super);
        }
}
View Code

示例6:super也可以访问方法

public class Test{
    public static void main(String[] args){
        Cat c = new Cat();
        c.yidong();
    }
}

class Animal{
    public void move(){
        System.out.println("Animal move!");
    }
}

class Cat extends Animal{
    @Override
    public void move(){
        System.out.println("Cat move!");
    }
    
    public void yidong(){
        this.move();
        move();
        //super不仅可以访问属性,也可以访问方法
        super.move();
    }
}
View Code

 


 

p70、this 详解

1、this在内存方面的特点综述:
  - this是一个变量,是一个引用,this保存当前对象的内存地址,指向对象自身,代表“当前对象”
  - 一个对象一个this,this存储在堆内存中对象的内部
  - this可以用在实例方法中,也可以用在构造方法中
  - 语法是“this”、“this.”、“this()”
  - this.大部分情况下可以省略,但是用来区分实例变量和局部变量的时候不能省略
  - this不能使用在静态方法中
  - this()这种语法只能出现在构造方法的第一行,表示当前构造方法调用本类中的其它构造方法,目的是代码复用

1)、this可以用在实例方法中代表当前对象
  - 谁(对象)调用这个实例方法,this就是谁
  - this可以调用本类的属性,也可以调用本类的其它方法
  - 表达式格式:
    this.属性名
    this.方法名(实参列表)

2)、“this.”大部分情况下是可以省略的,什么时候不能省略呢?
  - 在实例方法中或者构造方法中,为了区分实例变量和局部变量,这种情况下this是不能省略的
  如:public void setName(String name){
      this.name = name;
    }

3)、为什么this不能在静态方法中使用呢?
  - 因为this代表当前对象,静态方法中不存在当前对象

2、this还可以用在构造方法中
2.1、在当前的构造方法中使用this()语句调用本类的另一个构造方法,
  语法格式:
    this();
    this(实参列表);
  - 通过构造方法1去调用构造方法2,可以做到代码复用
  - 需要注意点是:两个构造方法必须是在同一个类当中
2.2、this()语句只能出现在构造方法的第一行,因此一个构造方法中只能有一个this()语句

示例1:this的应用

public class Test{
    public static void main(String[] args){
        
        Customer c1 = new Customer("张三");
        c1.shopping();
        
        Customer c2 = new Customer("李四");
        c2.shopping();
        
        Customer.doSome();
    }
}

class Customer{
    
    //实例变量
    String name;
    
    //构造方法
    public Customer(){}
    
    public Customer(String s){
        name = s;
    }
    
    //实例方法
    public void shopping(){
        //这里this是当前对象,this可以省略
        //c1调用shopping(),this就是c1,c2调用shopping(),this就是c2
        System.out.println(this.name + "正在购物!");
        System.out.println(name + "正在购物!");
    }
    
    //静态方法
    public static void doSome(){
        //this代表当前对象,而静态方法的调用不需要对象,矛盾了
        //错误:无法从静态上下文中引用非静态 变量 this
        //System.out.println(this.name);
        //创建对象访问实例变量
        Customer c = new Customer();
        System.out.println(c.name);
    }
}
View Code

示例2:this不能省略的用法

public class Test{
    public static void main(String[] args){
        Student s = new Student();
        s.setId(111);
        s.setName("张三");
        System.out.println("学号:" + s.getId());
        System.out.println("姓名:" + s.getName());
        
        Student s2 = new Student(222,"李四");
        System.out.println("学号:" + s2.getId());
        System.out.println("姓名:" + s2.getName());
    }
}

class Student{
    //学号
    private int id;
    //姓名
    private String name;

    //构造方法
    public Student(){}
    
    //使用见名知义形参,增强了程序的可读性
    public Student(int id,String name){
        this.id = id;
        this.name = name;
    }
    
    //get、set方法
    /*
    public void setId(int id){
        //就近原则,这两个id都是局部变量id,和实例变量id没关系,因此this不能省略
        id = id;
    }
    */
    public void setId(int id){
        //id是局部变量,this.id是实例变量
        //this.的作用是区分局部变量和实例变量
        this.id = id;
    }
    public int getId(){
        //teturn this.name; getId实际上获取的是当前对象的id,
        //严格来说,这里是有一个this.的,但是这个this可以省略
        return id;
    }
    
    /*
    public void setName(String name){
        //就近原则,这两个name都是局部变量name,和实例变量name没关系,因此this不能省略
        name = name;
    }
    */
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
View Code

 

示例3:this()语法用在构造方法中

public class Test{
    public static void main(String[] args){
        Date d1 = new Date();
        d1.detail();
        
        Date d2 = new Date(2008,8,8);
        d2.detail();
    }
}
/*需求:
1、定义一个日期类,可以表示年月日信息
2、需求中要求:
如果调用无参构造方法,默认创建的日期为:1970年1月1日
当然除了调用无参构造方法之外,也可以调用有参的构造方法来创建日期对象
*/
class Date{
    //
    private int year;
    //
    private int month;
    //
    private int day;

    //无参构造方法
    //初始化值是固定值
    public Date(){
        /*
        this.year = 1970;
        this.month = 1;
        this.day = 1;
        */
        //当前构造方法使用this()语法调用另一个构造方法,实现代码复用
        this(1970,1,1);
    }
    
    //有参构造方法
    public Date(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    
    //提供一个可以打印日期的方法
    public void detail(){
        System.out.println(this.year + "年" + this.month + "月" + this.day + "日");
    }

    //get/set方法
    public void setYear(int year){
        this.year = year;
    }
    public int getYear(){
        return year;
    }
    
    public void setMonth(int month){
        this.month = month;
    }
    public int getMonth(){
        return month;
    }
    
    public void setDay(int day){
        this.day = day;
    }
    public int getDay(){
        return day;
    }
}
View Code

示例4:一个综合性的练习题

//一个综合性的测试
public class Test{
    //实例变量
    int i = 10;
    
    //静态方法
    public static void dosome(){
        System.out.println("do some!");
    }
    
    //实例方法
    public void doOther(){
        System.out.println("do other!");
    }
    
    //静态方法
    public static void method1(){
        //调用doSome
        //使用完整方式调用
        Test.dosome();
        //使用省略方式调用
        dosome();
        
        //调用doOther
        //使用完整方式调用
        Test t = new Test();
        t.doOther();
        //不能使用省略方式调用
        
        //访问i
        //完整方式访问
        System.out.println(t.i);
        //不能使用省略方式访问
    }
    
    //实例方法
    public void mathod2(){
        //调用doSome
        //使用完整方式调用
        Test.dosome();
        //使用省略方式调用
        dosome();
        
        //调用doOther
        //使用完整方式调用
        this.doOther();
        //使用省略方式调用
        doOther();
        
        //访问i
        //完整方式访问
        System.out.println(this.i);
        //省略方式访问
        System.out.println(i);
    }
    
    //主方法
    public static void main(String[] args){
        //要求在这里编写程序调用method1
        //使用完整方式调用
        Test.method1();
        //使用省略方式调用
        method1();
        
        //要求在这里编写程序调用method2
        //使用完整方式调用
        Test t = new Test();
        t.method2();
        //不能使用省略方式调用
    }
}
View Code

 


 

p72 instanceof 运算符(参考多态章节)

1.1、instanceof 的意义
  - instanceof 用于在运行阶段动态判断引用指向的对象是否属于目标类型
  - instanceof 是一个逻辑运算符,运算符的结果是一个布尔值:true/false
1.2、instanceof 的语法机制
  - 首先编译阶段编译器只检查语法,检查左侧的引用的类型与右侧的目标类型是否相同,或者存在继承关系,是则编译通过,否则编译错误
  - 然后运行阶段进行判断运算instanceof运算,判断左侧的引用指向的对象是否属于目标类型,是则返回true,否则返回false

  - 表达式语法:
    (引用/对象 instanceof 类型名)
    if(引用/对象 instanceof 类型名){ 将引用向下转型 }
  如:Animal a = new Cat(); 【Animal a = new Bird(); 】 Bird b = (Bird)a;
  欲向下转型为Bird要先进行判断:(a instanceof Bird)
  编译阶段:先检查引用a的类型是Animal类型,与目标类型Bird存在继承关系,所以编译通过。
  运行阶段:再进行判断运算,即读作a是一个Bird吗?a的对象是一个Bird类的实例吗?a的对象是Bird类型吗?是则返回true,否则返回false

1.2、instanceof 的作用
  instanceof 只用于引用类型向下转型的判断运算,用来规避类型转换异常ClassCastException,不能用于基本数据类型

示例1:instanceof的使用

/*明明可以观察到底层对象到底是new Bird()还是new Cat()
为什么要进行instanceof的判断呢??
原因是:以后可能直接看不到了
*/
public class Test{
    public static void main(String[] args){
        Animal x = new Cat();
        Animal y = new Bird();
        
        /*错误:java.lang.ClassCastException: Cat cannot be cast to Bird
        Bird b = (Bird)x;
        b.sing();*/
        
        if(x instanceof Cat){
            Cat c = (Cat)x;
            c.catchMouse();
        }else if(x instanceof Bird){
            Bird b = (Bird)x;
            b.sing();
        }
        
        if(y instanceof Cat){
            Cat c = (Cat)y;
            c.catchMouse();
        }else if(y instanceof Bird){
            Bird b = (Bird)y;
            b.sing();
        }
    }
}

class Animal{
    public void move(){
        System.out.println("动物在移动!!!");
    }
}
class Cat extends Animal{
    @Override
    public void move(){
        System.out.println("cat走猫步!!!");
    }
    public void catchMouse(){
        System.out.println("cat正在抓老鼠!!!");
    }
}
class Bird extends Animal{
    @Override
     public void move(){
        System.out.println("bird在飞翔!!!");
     }
    public void sing(){
        System.out.println("bird在唱歌!!!");
    }
}
View Code

示例2:看不到真实的底层对象 向下转型须进行instanceof的判断

//直接看不到底层对象时,需要进行instanceof的判断
public class Test{
    public static void main(String[] args){
        //main方法是程序员A负责编写
        AnimalTest at = new AnimalTest();
        at.test(new Cat());
        at.test(new Bird());
    }
}

class AnimalTest{
    /*test方法是程序员B负责编写
    test方法的参数是一个Animal
    此方法别人会拿去调用,调用时可能给test()方法传递一个Bird,也可能传递一个Cat
    对我来说,我不知道test()方法被调用时传过来的是什么
    */
    public void test(Animal x){
        if(x instanceof Cat){
            Cat c = (Cat)x;
            c.catchMouse();
        }else if(x instanceof Bird){
            Bird b = (Bird)x;
            b.sing();
        }
    }
}

class Animal{
    public void move(){
        System.out.println("动物在移动!!!");
    }
}
class Cat extends Animal{
    @Override
    public void move(){
        System.out.println("cat走猫步!!!");
    }
    public void catchMouse(){
        System.out.println("cat正在抓老鼠!!!");
    }
}
class Bird extends Animal{
    @Override
     public void move(){
        System.out.println("bird在飞翔!!!");
     }
    public void sing(){
        System.out.println("bird在唱歌!!!");
    }
}
View Code

 

 示例3:instanceof的语法机制

public class Test{
    public static void main(String[] args){
        
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Student s1 = new Student();
        Person s2 = new Student();
        Object s3 = new Student();
        
        //测试instanceof运算符的用法
        System.out.println(s1 instanceof Student); //true
        System.out.println(s1 instanceof Person); //true
        System.out.println(s1 instanceof Object); //true
        //System.out.println(s1 instanceof Teacher); //编译错误
        //System.out.println(s1 instanceof String); //编译错误
        
        System.out.println(s2 instanceof Student); //true
        System.out.println(s2 instanceof Person); //true
        System.out.println(s2 instanceof Object); //true
        System.out.println(s2 instanceof Teacher); //false
        //System.out.println(s2 instanceof String); //编译错误
        
        System.out.println(s3 instanceof Student); //true
        System.out.println(s3 instanceof Person); //true
        System.out.println(s3 instanceof Object); //true
        System.out.println(s3 instanceof Teacher); //false
        System.out.println(s3 instanceof String); //false
        
        System.out.println(new Student() instanceof Student); //true
        System.out.println(new Student() instanceof Person); //true
        System.out.println(new Student() instanceof Object); //true
        //System.out.println(new Student() instanceof Teacher); //编译错误
        //System.out.println(new Student() instanceof String); //编译错误
    }
}

class Person{}
class Student extends Person{}
class Teacher extends Person{}
View Code

 


 

p73 static 关键字
1、static 翻译为静态的,是用来修饰方法或属性的

  * 静态变量在类加载的时候初始化,内存在方法区内存中开辟,因此访问静态变量不需要创建对象,直接使用类名访问
  * 所有static修饰的元素都称为静态的,都是通过“类名.”访问
  * 所有static修饰的元素都是类级别的,是类的模板特征,和具体的对象无关

1)什么时候成员变量声明为静态变量/静态方法呢?
  - 对于这个类型的所有对象,当某个属性的值都是一样的,不因对象不同而不同,建议定义为类级别特征,定义为静态变量,在方法区中只保留一份,节省内存的开销
  - 方法描述的是行为/动作,当所有的对象执行这个行为/动作,产生的结果是一样的时候,那么这个动作已经不在属于具体对象的动作了,可以将这个动作提升为类级别的动作模板级别的动作
2)什么时候成员变量声明为实例变量/实例方法呢?
  - 对于这个类型的所有对象,不同的对象其属性的具体值不同,那么该属性须定义为实例变量
  - 当执行一个行为/动作过程中,如果该行为需要对象去触发,不同对象执行的结果是不一样的,那么该方法定义为“实例方法”
  - 如果中一个方法中直接访问了实例变量,那么该方法也必须是实例方法

3)如何访问静态的与实例的变量/方法?
  - 所有静态相关的都是通过“类名.”访问,如果是在同一个类中“类名.”可以省略
  - 所有实例相关的都需要先创建对象,采用“引用.”或“this.”的方式访问,如果是在同一个类中“this.”可以省略

4)详解编译错误:无法从静态上下文中引用非静态的变量/方法
- 从静态上下文中只能访问静态相关的东西,并且只能通过“类名.”访问
- 在静态方法中,不能直接访问实例的,必须先new对象,使用“引用.”访问,也不能使用this引用,因为静态方法中没有this
- 从非静态上下文中既可以访问静态相关的,也可以访问实例相关的
- 在实例方法中,访问静态相关的可以采用“类名.”的方式访问,也可以采用“引用.”的方式访问,但实际执行的过程还是类名访问
- 在实例方法中,访问实例相关的只能采用“引用.”的方式访问

4、静态导入包
  - 用静态的办法导入包中类的方法,就可直接调用该类的方法或常量

  如:import static java.lang.Math.*;

 //示例10-1:static 的用法测试

//static 的用法测试
public class Student{
    
    private static int age;    //静态变量
    private double score;    //非静态变量
    
    public void run(){
        System.out.println("run");
    }
    
    public static void go(){
        System.out.println("go");
    }
    
    public static void main(String[] args){
        Student s1 = new Student();
        
        //静态变量可以通过类访问,也可以通过对象访问
        //静态变量属于当前类时甚至可以直接访问
        //非静态变量只能通过对象访问
        System.out.println(Student.age);
        System.out.println(s1.age);
        System.out.println(age);
        System.out.println(this.age);
        System.out.println(s1.score);
        
        
        //方法的调用同理
        s1.run();
        Student.go();
        s1.go();
        go();
        this.run();
    }
}
View Code

//示例10-3:静态导入包的测试

//Math类的方法都是静态的,可以通过类调用,不用导入包,
//import java.lang.Math;
public class T10{
    public static void main(String[] args){
        
        //输出一个随机数
        System.out.println(Math.random());
        System.out.println(Math.PI);
    }
}


//静态导入包
//Math类里的方法可以用static的办法导入,然后就能直接调用
import static java.lang.Math.*;
public class T11{
    public static void main(String[] args){
        
        //输出一个随机数
        System.out.println(random());
        System.out.println(PI);
    }
}
View Code

 //示例10-4:static的用法,private的用法,get/set的用法,全局变量的使用

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

        Student s1 = new Student();

        //静态变量可以通过类访问,也可以通过对象访问
        //非静态变量只能通过对象访问
        Student.name = "小强";
        s1.sex = true;
        System.out.println(Student.name);//System.out.println(s1.name);
        System.out.println(s1.sex);
        //Student.sex = true;       //编译报错
        //System.out.println(Student.sex);  //编译报错

        //静态的方法,可以通过类调用,也可以通过对象调用
        //非静态的方法只能通过对象调用
        Student.go();//s1.go();
        s1.run();
        //Student.run();    //编译报错

        //private属性私有,必须通过get/set入口访问
        //Student.age = 15;     //private 访问控制
        //s1.score = 87.5;      //private 访问控制
        //System.out.println(Student.age);  //private 访问控制
        //System.out.println(s1.score);     //private 访问控制

        //静态的get/set方法,可以通过类调用,也可以通过对象调用
        Student.setAge(13);
        System.out.println("学生的虚岁年龄是:" + s1.getAge());
        //非静态的get/set方法只能通过对象调用
        s1.setScore(87.5);
        System.out.println("加分后:" + s1.getScore());
    }
}


public class Student{

    public static String name;    //静态变量
    public boolean sex;        //非静态变量
    private static int age;    //静态变量
    private double score;    //非静态变量

    //当前类的成员变量都是全局变量,一般可以直接调用
    //- 从静态上下文中只能引用静态的变量,不能引用非静态的变量
    //- 从非静态上下文中既可以引用静态变量,也可以引用非静态变量
    //- 在静态上下文中,静态变量可以使用类引用,不能使用this引用
    //- 在非静态上下文中,静态变量既可以使用类引用,也可以使用this引用
    //- 非静态变量可以使用this引用,却不能使用类引用
    //静态方法
    public static void go(){
        name = "小明";    // 或者Student.name = "小明";
        age = 11;        // 或者Student.age = 11;
        //sex = true;   //编译错误
        //score = 67.5; //编译错误
        System.out.println("go方法执行了," + name + age);
        //System.out.println(sex + score);//编译错误
    }
    //非静态方法
    public void run(){
        name = "小花";   //或者Student.name = "小明";this.name = "小明";
        age = 12;       //或者Student.age = 11;this.age = 11;
        sex = false;    //this.sex = false;
        score = 77.5;   //this.score = 86.5;
        System.out.println("run方法执行了," + name + sex + age + score);
    }

    //private修饰的数据只能在当前类中访问
    //为外部程序提供get/set入口
    public static int getAge() {
        age++;
        return age;
    }
    public static void setAge(int ag) {
        Student.age = ag;
        System.out.println(name + "设定的年龄是:" + age);
    }

    public double getScore() {
        score++;
        return score;
    }
    public void setScore(double scr) {
        this.score = scr;
        System.out.println("输入的成绩是:" + score);
    }
}
View Code

 


 

155、final 关键字

1、final 表示最终的最后的,不可变的
2、final可以修饰变量、方法、类等
1)final修饰的类无法被继承
  如果你不希望该类被继承扩展,就可以给该类加final修饰,从而不扩展子类,如:pubic final class person{}
2)ifnal修饰的方法无法被覆盖被重写,
  父类的方法使用final修饰才有意义,可以继承
3)final修饰的变量只能赋值一次,无法修改,一旦赋值不能重新赋值
3.1)final修饰的局部变量,只能赋值一次
3.2)final修饰的实例变量,必须手动初始化,不能采用系统默认值
  由于实例变量如果没有手动赋值的话,系统会赋默认值,而final修饰的实例变量一旦赋值将无法修改,因此为了有效初始化,sun公司决定,系统不负责赋默认值,要求程序员必须手动赋值
  手动为变量赋值,可以在声明表达式右侧赋值,也可以在构造方法中赋值
3.3)final修饰的实例变量一般要添加static修饰,static final 联合修饰的变量称为“常量”

  常量名的字母全部大写,单词之间使用下划线连接
  实例变量既然已经使用了final修饰,说明该变量的值不会因对象不同而变化,因此该实例变量应该添加static修饰,变为静态的
  常量和静态变量一样,存储在方法区,都是在类加载时初始化,区别是常量的值不变,因此常量一般是公共的public的
  * 常量的语法结构:
    public static final 类型 常量名 = 值;
    public static final double PI = 3.14159265358979;
3.4)final修饰的引用,引用指向的对象无法修改,不能重新指向其它对象,但是对象内部的数据是可以修改的
  在当前方法执行过程中,引用指向的对象不能被垃圾回收器回收,直到该方法执行结束后才会释放空间
  即使引用赋空值null时同样不可修改

3、总结:
1)final修饰的类无法被继承
2)ifnal修饰的方法无法被覆盖被重写,
3)final修饰的变量只能赋值一次,无法修改
4)final修饰的实例变量,必须手动初始化
5)final修饰的实例变量一般要添加static修饰,static final 联合修饰的变量称为“常量”
6)final修饰的引用,引用指向的对象无法修改,但是对象内部的数据是可以修改的

示例1:常量、static、PI

public class Test{
    public static void main(String[] args){
        System.out.println(Chinese.COUNTRY);
        System.out.println("圆周率:" + MyMath.PI);        
    }
}

class MyMath{
    public static final double PI = 3.14159265358979;
}

class Chinese{
    //每一个中国人的国籍都是中国,而国籍不会发生改变,为了防止国籍被修改,建议加final修饰
    public static final String COUNTRY = "中国";
View Code

 


 

补充知识:

1、replaceAll("A","B")
:字符串替换,将字符串对象中的原字符串A全部替换为B,并返回一个新字符串对象,replaceAll(String regex,String replacement){},
    String newString = 字符串对象. replaceAll("原字符串", "新字符串")

//示例:字符串替换方法:replaceAll()

public class Replace{
    //将所有的"a"字符串替换为"x"
    public static void main(String[] args){
        String newString = "adfjlsdvncxoauweoas".replaceAll("a","x");
        System.out.println(newString);
    }
}
View Code

 

2、Date类
  import java.util.Date;
  new Date();  //返回系统当前时间

示例:读取系统当前时间

import java.util.Date;
public class Test{
    public static void main(String[] args){
        Date date = new Date();
        System.out.println("当前时间为:" + date);        
    }
}
View Code

 

 

 

 

 

 

 

 

//即使再小的帆也能远航2021-11-09

posted @ 2021-11-09 17:38  冬雪雪冬小大寒  阅读(105)  评论(0)    收藏  举报