面向对象-oop-5-名词解释、静态

  • 名词解释
    • 成员变量
      • 实例变量:其实就是对象
      • 静态变量:属于类,存在方法区
    • package:
      • 避免类的命名冲突,同包类中的类不能同名
      • 类的全称:包名.类命
      • 包名常常有层次结构cm.csdn.oop
      • 建议:包名所有字母都小写
    • import:
      • 同包中的类可以直接访问
      • 不同包中的类不能直接访问,若访问需要用import引用
    • 访问控制修饰符:数据(成员变量)私有化,行为(方法)公开化(我有嘴巴,有耳朵,这是我的私有的,但是我会唱歌,会跳舞,会跑步,这是我的行为公开的)
      • public:公开的,任何类
      • protected:受保护的,本类、派生类、同包类
      • default(默认)不写:什么也不写,本类,同包类(同包类可以继承,夸包就不可以了),
      • private:私有的,本类
        • private修饰的静态方法和静态变量,只能在本类中使用;
        • private修饰的方法和属性是私有的,只能在本类中使用,不能被继承。
      • 说明:
        • 类的访问权限只能是public或默认的,夸包的情况下,只有public可以被继承,一个类只能有一个public 可以有多个默认的
        • 类中成员的访问权限如上四种都可以
        • 属性的可见性有四种:公有的(public)、保护的(protected)、默认的(default)、私有的(private)
        • 就是当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。java内存模型在变量修改后将新的变量值同步回主内存,在其他线程读取该变量之前从主内存刷新变量值来实现可见性。
        • 对于顶层类(外部类)来说,只有两种修饰符:public和默认(default)。 因为外部类的上一单元是包,所以外部类只有两个作用域:同包,任何位置。 因此,只需要两种控制权限:包控制权限和公开访问权限,也就对应两种控制修饰符:public和默认(default)。 但是private可以修饰class的,只不过该类不能是顶层类,可以是内部类 内部类的上一级是外部类,那么对应的有四种访问控制修饰符:本类(private),同包(default),父子类(protected),任何位置(public)。 当一个内部类使用了private修饰后,只能在该类的外部类内部使用
        • 方法中定义的是局部变量,不能用类成员变量修饰符 private。
public class Something {
    private String s="";
    void doSomething () {
         //private String s = ""; //此处编译错误错误
        int l = s.length();
    }
}

(单选题)下列哪种说法是正确的(D )
A.本类中实例方法可以调用其他类中所有实例方法 
B.本类中实例方法可以调用其他类中类方法 
C.本类中实例方法可以直接通过方法名调用其他类的实例方法 
D.本类中实例方法可以直接通过方法名调用本类中其他实例方法 


A. 本类实例方法不可以调用其他类的私有实例方法。
B. 本类实例方法不可以调用其他类的私有类方法。
C.本类实例方法不可以直接通过方法名调用其他类的实例方法。

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

    void temp(){
        show();
    }
  • final:最终的、不可改变的
    • 修饰变量:变量不能改变
    • 修饰方法:方法不能重写
    • 修饰类:类不能继承
    • final方法为最终方法,不可修改,即子类不可以覆盖父类的final方法
    • final变量 为常量 一旦声明,就不可修改
    • final类为最终类,不可以扩展,即不可以被继承
    • 子类可以继承父类的中非私有的方法、变量,构造方法也不可以
  • 注意:如下两个案例:final修饰引用类型,是引用不能改变,而引用指向的内容是可以改变的。
public static void main(String args[]){
        final Student stu1 = new Student("Tom",25);
        Student stu2 = new Student("Jerry",23);
        //stu1 = stu2;编译错误,stu1是final修饰的,引用不能改变

        stu2 = stu1;                //stu2没有被file修饰,所以地址可以改变
        stu1.setName("Jerry");      //引用指向的对象是可以改变的
        stu1.setAge(25);            //引用指向的对象是可以改变的
 }
//此代码段就是final修饰引用类型,引用不能改变,但是内容是可以改变的
public class Something {
  public static void main(String[] args) {
    Other o = new Other();
    new Something().addOne(o);
  }
  public void addOne(final Other o) {
    o.i++;
  }
}
class Other {
  public int i;
} 


//错误示例:此代码段就是final修饰变量的,变量不能被改变
public class Something {
  public int addOne(final int x) { 
     //return ++x;   编译错误, final 修饰为常量,常量的值不能被改变。
       return 0;
  }
} 
  • static:
    • 静态的,类在编译的时候生成java.class字节码文件,存在于方法区;
    • 静态在加载运行的时候 只会执行一次,不会再被初始化了
    • 类的实例方法存在一个专门的区叫方法区,事实上类刚加载的时候就被加载好了,不过它们在"睡眠"状态,这些方法必须当有对象产生的时候才会"苏醒"
    • 静态的东西存在静态区,他们和类是一个等级的,就是说只要类被加载,它们就可以直接用(用类名来调用)
    • 类方法、变量可以通过类命.来调用;(也可以通过对象来调用,不过我们不推荐用对象调用)
    • 注意:普通方法可以直接调用静态变量
    • 静态块是类加载的时候就会被执行到的,静态执行顺序是按照在类中出现 的先后顺序执行。 静态变量-静态块-静态方法-构造方法
public class Images {
    //构造方法
    private Images(){
        
    }
    //静态变量
    public static BufferedImage start;
    //静态块
    static {
        start = getImage("start.png");
    }
    //静态方法
    public static BufferedImage getImage(String path){
        try {
            ImageIO.read(FlyingObject.class.getResource(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • 这里引入了一个静态构造方法,什么是静态构造方法?如下:
public class Test1 {
    public static void main(String[] args) {
        Doctor = null;
        /**
         * 声明对象,不会报错
         * 实例化对象,调用了私有化的构造方法,程序报错
         * 如下:
         * s = new Doctor();//错误,无法实例化对象
         */
        
    }
}
//String 构造
class Doctor{
    private Doctor(){
        //将构造方法进行了封装私有化,那么此构造方法只能在本类中可见!
    }
}


//因为Doctor类中的构造方法被私有化了,
//只能在本类Doctor中可见,
//不能再外部直接实例化!只能在Doctor 内部使用!
//而我们创建对象其实就是new 构造方法



所以封装,不仅体现在类的封装、属性的封装、也有方法的封装、那就包括构造方法
构造方法可以被封装为任意四种类型
public class Test2 {
    public static void main(String[] args) {
        //声明对象,不会报错
        Teacher s = null;
    }
}

class Teacher{
    //在内部产生本类的实例化对象
    Teacher teacher = new Teacher();
    private Teacher(){
        //将构造方法进行了封装私有化,此构造方法只能在本类中可见!
    }
}
  • 静态方法只能调用静态的东西,即使new对象,对象向的属性也得是静态的
  • 普通方法可以调用非静态的 
 public static void main(String[] args) {
        getInstance();
    }
    public static void getInstance(){
        Teacher teacher = new Teacher();
    }
    static class Teacher{
        //在内部产生本类的实例化对象
        Teacher teacher = new Teacher();
        private Teacher(){
            //将构造方法进行了封装私有化,此构造方法只能在本类中可见!
        }
    }
private Test(){}
    private static Test test;
    public static Test getInstance(){
        return test = new Test();
    }

  • 静态变量:
    • 由static修饰
    • 静态成员只会初始化一次
    • 属于类,存在方法区中,只有一份
    • 常常通过类命点来访问
    • 何时用:所有对象所共享的数据(图片、音频、视频等)
  • 静态方法:
    • 由static修饰
    • 属于类,存在方法区中,只有一份
    • 常常通过类命点来访问
    • 静态方法中没有隐士this传递,在静态方法中不能直接访问实例成员。静态方法中只能访问静态变量 有个默认类.静态变量,不写有默认
class StaticStuff{		
  static int x=10;
  static{
     x+=5;
  }
  public static void main(String args[]){
    //静态方法访问其他实例需要new 对象,用对象的引用去访问
    
    System.out.println("x=" + x);    //同一个类中,静态访问静态,类命不写有默认,
    ||
    System.out.println("x=" + StaticStuff.x);
  }
  static {
    x/=3;
  }
}
  • 在类方法中可以通过实例化对象调用实例方法。
  • 何时用:方法的操作与对象无关
  • 静态块:static{ }
    • 由static修饰
    • 属于类,在类被加载时自动执行,一个类只被加载一次,所以静态块也只执行一次
    • 何时用:初始化/加载静态资源(图片、音频、视频等)
  • 案例:
//static的演示
public class StaticDemo {
public static void main(String[] args) {

        //加载Noo.class到方法区中,同时系统会自动执行静态块,静态只执行一次
        Noo o4 = new Noo();
        Noo o5 = new Noo();
        Noo o6 = new Noo();
        //静态块
        //构造方法
        //构造方法
        //构造方法
    }
}

class Noo{ //演示静态块
    static {
        System.out.println("静态块");
    }
    Noo(){
        System.out.println("构造方法");
    }
}
class Loo{ //演示静态变量
    int a; //实例变量
    static int b; //静态变量
    Loo(){
        a++;
        b++;
    }
    void show(){
        System.out.println("a="+a+",b="+b);
    }

//静态成员存在方法区,因为类只会被加载一次,所以静态也只会被初始化一次
    public static void main(String[] args) {
        Loo a = new Loo();
        a.show();//1,1

        Loo b = new Loo();
        a.show();//1,2

        Loo c = new Loo();
        a.show();//1,3
    }
class Moo{ //演示静态方法
    int a;        //实例变量(对象点来访问)
    static int b; //静态变量(类名点来访问)

    void show(){ //有this传递
        System.out.println(this.a);
        System.out.println(Moo.b);
    }
    static void test(){
        /**
         * 静态方法中没有隐式this传递,没有this就意味着没有对象
         * 而实例变量a必须通过对象来访问
         * 所以如下代码发生编译错误:
         * System.out.println(a); //编译错误
         */
        System.out.println(Moo.b);
    }
}
  • 内存图:类.class文件先被加载到方法区,1、方法区(类.class字节码文件、静态),2、堆(对象、实例),3、栈(变量、方法参数)

  • 注意:静态方法
    • 可以继承和隐藏 
    • 不能被重写
    • 不能实现多态
    • 不能实现父类的引用可以指向不同子类的对象进行多态调用。
    • 如果调用的是静态方法,类型是谁,调用的就是谁的
class Super {
	public static void m1() {
		System.out.println("m1 in Super");	
    }
	public void m2() {
		System.out.println("m2 in Super");	
    }
}

class Sub extends Super {
	public static void m1() {
		System.out.println("m1 in Sub");	
    }
	public void m2() {
		System.out.println("m2 in Sub");	
    }
}

public class TestMain {
	public static void main(String args[]) {
		Super sup = new Sub();
		sup.m1();
		sup.m2();
		Sub sub = (Sub) sup;
		sub.m1();
		sub.m2();	}
}

m1 in Super
m2 in Sub
m1 in Sub
m2 in Sub

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值