Unit04

Unit04  -  继承的意义(下) 、 访问控制 、 static和final

1.方法的重写(Override):重新写、覆盖
  1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
  2)重写方法被调用时,看对象的类型


2.方法重写与重载的区别:------常见面试题
  1)重写(Override):
    1.1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
    1.2)遵循"运行期"绑定,根据对象的类型来调用方法
  2)重载(Overload):
    2.1)发生在同一类中,方法名称相同,参数列表不同,方法体不同
    2.2)遵循"编译期"绑定,根据引用(参数)的类型来绑定方法


3.package:
  1)作用:避免类名的冲突
  2)包名可以有层次结构
  3)类的全称: 包名.类名
  4)建议:包名所有字母都小写
  import:
  1)同包中的类可以直接访问
  2)不同包中的类不能直接访问,方式如下两种:
    2.1)先import声明类而后再直接使用---建议
    2.2)类的全称------太繁琐,不建议


4.访问控制修饰符:
  1)public:公开的,任何类
  2)private:私有的,本类
  3)protected:受保护的,本类、子类、同包类
  4)默认的:什么也不写,本类、同包类
  类的访问修饰符有:public和默认的
  类中成员的访问修饰符有:如上4种都可以


5.static:静态的
  1)静态变量:
    1.1)由static修饰
    1.2)属于类的,存储在方法区中,只有一份
    1.3)常常通过类名点来访问
    1.4)何时用:所有对象所共享的数据(图片、音频、视频等)
  2)静态方法:
    2.1)由static修饰
    2.2)属于类的,存储在方法区中,只有一份
    2.3)常常通过类名点来访问
    2.4)静态方法没有隐式的this传递,
        静态方法中不能直接访问实例成员
    2.5)何时用:方法的操作仅与参数相关而与对象无关
  3)静态块:
    3.1)由static修饰
    3.2)属于类的,在类被加载期间自动执行,
        类只被加载一次,所以静态块也只执行一次
    3.3)何时用:常常用于初始化静态资源(图片、音频、视频等)


6.final:最终的
  1)修饰变量:变量不可被改变
  2)修饰方法:方法不可被重写
  3)修饰类:  类不可被继承
 
 静态方法
 静态方法没有隐式this,
没有this意味着没有对象,
没有对象就无法直接访问实例成员,
因为实例成员必须得对象来访问

成员变量:
1)实例变量:

没有static修饰
属于对象的,存储在堆中,
有几个对象就有几份
通过对象点来访问


2)静态变量:

有static修饰
属于类的,存储在方法区中,
只有一份
通过类名点来访问   
           
与对象无关-------适合静态
与对象有关-------不适合静态

静态类:
无论a1,a2,a3,...,a100,
  去sort(arr),最终的结果都一样
  说明sort()方法,与对象无关,而仅与参数相关

Arrays.sort(arr);
假设sort()不是静态的:
  Arrays a1 = new Arrays();
  a1.sort(arr);

  Arrays a2 = new Arrays();
  a2.sort(arr);

  Arrays a3 = new Arrays();
  a3.sort(arr);

无论m1,m2,m3...,m100,
  去sqrt(25),最终结果都是一样的
  说明,sqrt()方法与对象无关,而仅与参数相关

double a = Math.sqrt(25);
假设sqrt()不是静态的
  Math m1 = new Math();
  double a = m1.sqrt(25);

  Math m2 = new Math();
  duoble b = m2.sqrt(25);
 
  Math m3 = new Math();
  double c = m3.sqrt(25);


数据私有化(private),行为公开化(public):
class Card{
  private String cardId;
  private String cardPwd;
  private double balance;

  public boolean payMoney(double money){
    if(balance>=money){
      balance-=money;
      return true;
    }else{
      return false;
    }
  }
  public boolean checkPwd(String pwd){
    if(pwd.equals(cardPwd)){
      return true;
    }else{
      return false;
    }
  }
}

建议命名规则:
  域名反写    . 项目名称 . 模块名称 . 类名
  cn.tedu     . a        .  student  .
  com.taobao  . b        .  teacher  .
  com.jd

重载看引用,重写看对象

编译期:.java,经编译,生成.class-----检查语法
运行期:JVM加载.class并运行.class-----加载对象

重写:继承了一个餐厅(中餐)
A:继承后依然还是做中餐---------不需要重写
B:继承后改为做西餐-------------重写
C:继承后在中餐基础上加西餐-----重写+super

静态变量

OverrideDemo,练习重写

package oo.day04;
//重写的演示
public class OverrideDemo {
    public static void main(String[] args) {
        
    }
}
/*
 * 重写需遵循"两同两小一大"原则:
 * -----------一般都是一模一样
 * 1)两同:
 *   1.1)方法名称相同
 *   1.2)参数列表相同
 * 2)两小:
 *   2.1)子类方法的返回值类型小于或等于父类的
 *       2.1.1)void时,必须相等
 *       2.1.2)基本类型时,必须相等
 *       2.1.3)引用类型时,小于或等于
 *   2.2)子类方法抛出的异常小于或等于父类的-----异常之后
 * 3)一大:
 *   3.1)子类方法的访问权限大于或等于父类的-----访问控制修饰符之后
 */

//父类大,子类小
class Aoo{
    void say(){}
    double sayHi(){return 0.0;}
    public Aoo test(){return null;}
    Boo show(){return null;}
}
class Boo extends Aoo{
    //int say(){return 1;} //编译错误,void时必须相等
    //int sayHi(){return 0.0;} //编译错误,基本类型时必须相等
    public Boo test(){return null;} //正确,引用类型小于
    //Aoo show(){return null;} //编译错误,引用类型必须小于或等于
}

OverloadOverrideDemo,练习重写与重载的区别

package oo.day04;
//重写与重载的区别
public class OverloadOverrideDemo {
    public static void main(String[] args) {
        //重载看引用,重写看对象
        Eoo eoo = new Eoo();
        Coo o = new Doo(); //向上造型
        eoo.test(o); //重载看引用(参数)
    }
}

class Eoo{
    void test(Coo o){
        System.out.println("父型参数");
        o.show(); //重写看对象
    }
    void test(Doo o){
        System.out.println("子型参数");
        o.show();
    }
}

class Coo{
    void show(){
        System.out.println("父类Show");
    }
}
class Doo extends Coo{
    void show(){
        System.out.println("子类Show");
    }
}

StaticDemo,练习static

自己整理的:

package oo.day04.vis;

public class StaticDemo {

    public static void main(String[] args) {
        Joo o1 = new Joo();
        o1.show();
        
        Joo o2 = new Joo();
        o2.show();
        
        System.out.println(Joo.b);    //2,刚刚已经长成2了
        
        Koo.test();        //因为是静态的,所以通过类名访问
        
        Loo o3 = new Loo();        //加载类的时候自动执行,只执行一次,类只加载一次
        Loo o4 = new Loo();        //加载过了,方法区不变,直接执行构造方法,
    }

}

class Loo{
    static {
        System.out.println("静态块");
    }
    
    Loo(){
        System.out.println("构造方法");
    }
}


class Koo{
    int a;            //对象访问
    static int b;    //类访问
    void show(){        //有隐藏的this
        System.out.println(a);    //this.b
        System.out.println(b);    //Koo.b
    }
    static void test(){    //没有隐式this传递
//        System.out.println(a);        //没有this方法,报错,a必须要要通过对象访问
        System.out.println(b);        //通过类名访问
    }
}


class Joo{
    int a;            //实例变量
    static int b;    //静态变量
    
    Joo(){
        a++;
        b++;
    }
    void show(){
        System.out.println("a="+a);
        System.out.println("b="+b);
    }
}


//静态方法不能直接访问实例成员??
class Aoo{
    int a;        //实例变量        对象点
    static int b;    //静态变量        类名点      属于类
    void show(){    //实例方法        有隐式this
        System.out.println(a);    //this.a
        System.out.println(b);    //Aoo.b
    }
    
    static void test(){    //静态方法        没有隐式this
//        System.out.println(this.a);      //编译错误
        System.out.println(b);
    }
}
StaticDemo.java

老师的:

package oo.day04;
//static的演示
public class StaticDemo {
    public static void main(String[] args) {
        Joo o1 = new Joo();
        o1.show();
        Joo o2 = new Joo();
        o2.show();
        System.out.println(Joo.b); //2
        System.out.println(o1.b); //2,不建议
        System.out.println(o2.b); //2
        
        Koo.test();
        
        Loo o3 = new Loo();
        Loo o4 = new Loo();
    }
}

class Loo{ //演示静态块
    static{
        System.out.println("静态块");
    }
    Loo(){
        System.out.println("构造方法");
    }
}


class Koo{ //演示静态方法
    int a;
    static int b;
    void show(){
        System.out.println(a);
        System.out.println(b);
    }
    static void test(){ //没有隐式this传递
        //System.out.println(a); //没有this意味着没有对象,而a必须要通过对象来访问,所以编译错误
        System.out.println(b);
    }
}

class Joo{ //演示静态变量
    int a; //实例变量:堆中,有几个对象有几份
    static int b; //静态变量:方法区中,一份
    Joo(){
        a++;
        b++;
    }
    void show(){
        System.out.println("a="+a);
        System.out.println("b="+b);
    }
}
演示final
package oo.day04;
//final的演示
public class FinalDemo {
    public static void main(String[] args) {
        
    }
}

final class Poo{} //演示final修饰类
//class Qoo extends Poo{} //编译错误,final的类不能被继承

class Roo{}
final class Soo extends Roo{}

class Noo{ //演示final修饰方法
    void show(){}
    final void test(){}
}
class Ooo extends Noo{
    void show(){}
    //void test(){} //编译错误,final的方法不能被重写
}

/*
 * final可以修饰成员变量,只有两种初始化方式:
 *   1)声明同时初始化
 *   2)构造方法中初始化
 * final可以修饰局部变量,只要在使用之前初始化即可
 */
class Moo{ //演示final修饰变量
    final int a = 5;
    final int b;
    Moo(){
        b = 6;
    }
    void show(){
        final int c; //用之前初始化即可
        //a = 55; //编译错误,final的变量不能被改变
    }
}

程序一:演示public,protected,private

package oo.day04;

public class Foo {
    public int a;    //任何类
    protected int b; //本类、子类、同包类
    int c;           //本类、同包类
    private int d;   //本类
    
    void show(){
        a = 1;
        b = 2;
        c = 3;
        d = 4;
    }
}

class Goo{ //演示private
    void show(){
        Foo o = new Foo();
        o.a = 1;
        o.b = 2;
        o.c = 3;
        //o.d = 4;
    }
}
Foo.java
package oo.day04.vis;
import oo.day04.Foo;

public class Hoo { //演示包
    void show(){
        Foo o = new Foo();
        o.a = 1;
        //o.b = 2;
        //o.c = 3;
        //o.d = 4;
    }
}

class Ioo extends Foo{ //演示protected,跨包继承
    void show(){
        a = 1;
        b = 2;
        //c = 3;
        //d = 4;
    }
}
Hoo.java
原文地址:https://www.cnblogs.com/tangshengwei/p/6172092.html