Week2 数组及面向对象初认识(个人笔记)

本文详细介绍了Java中数组和面向对象编程的相关知识。包括一维、二维数组的定义、初始化及内存分配,面向对象思想、对象初始化过程、成员变量与局部变量区别等。还阐述了继承、static关键字、代码块、final关键字等内容,并给出相关面试题分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.数组

    1.一维数组:

       a.定义格式:数据类型 [] 数组名  (推荐使用)   如:int[]  a   ; 数据类型 数组名 []  如:int a[]

       b.初始化:

  • 动态初始化:只给出数组长度,系统默认初始值   如:int []  a=new int[10];
  • 静态初始化:给出值,系统默认长度  如:int [] a={1,2,3};
  • 注意事项:   静态初始化和动态初始化不同同时使用 如:  int[] arr = new int[3] {1, 2, 3}  //错误

       c.初步了解java内存分配:

          :存储局部变量(在方法定义或方法声明中定义的变量),栈中的数据使用完毕就消失;

          堆:new出来的东西;每一个new出来的东西均有地址,每一个new出来的东西均有默认值;数据使用完毕后,就会变成垃

                 圾,在垃圾回收器空闲的时候被其回收。

          方法区:存放方法及常量;

          本地方法区(与系统文件相关):

          程序计数器:存放字节码指令的地址,控制指令的执行顺序。 

        

         d.数组内存图:

            int[] a=new int[3];

            

 

          第一步:在栈中声明一个数组变量a,其空间是4个字节(变量名都为4个字节);

          第二步:在堆中开辟一个长度为3的数组,并将数组元素赋予初始值0;

          第三步:将堆中数组的地址(逻辑地址)存入变量a中;

          

2.二维数组:

   (1)元素是一维数组的数组。
   (2)格式:

  •         A: int[][] arr = new int[3][2]; //看作3个长度为2的数组
  •         B: int[][] arr = new int[3][];初始化:arr[0]=new int[2]; arr[1]=new int[3]; arr[2]=new int[1];
  •         C: int[][] arr = new int[][] {{1, 2, 3}, {4, 5}, {6}};
  •         简化格式 int[][] arr = {{1, 2, 3}, {4, 5}, {6}};

    (3)三种格式的内存图:

    A: 

    

    B:

             

    null表示将该内存区域清空,不指向任何区域。

    C:

          

二:面向对象思想:程序等于=对象+消息;

洗衣服:
    面向过程:把脏衣服放在桶里 --> 加洗衣粉 --> 到水,浸泡半小时 --> 搓上10分钟 --> 清洗 --> 拧干 --> 晾衣服
    面向对象:把脏衣服放在桶里 --> 洗衣机(洗衣服) --> 晾衣服

    把专业的事情交给专业的人去做。
 

对象的初始化过程:

Student s=new Student();

代码:Student s = new Student();做了哪些事情?

  •     (1)加载Student.class到内存
  •     (2)在栈上开辟为s变量开辟内存空间
  •     (3)在堆上申请为对象申请内存空间
  •     (4)对对象的成变量进行默认初始化
  •     (5)对成员变量进行显示初始化
  •     (6)执行构造方法
  •     (7)将对象的地址赋值给s变量

一个对象的内存图:

 

class Tel {
    String brand;
    double price;
    String color;
    public void call(String name) {
        System.out.println("我给" + name + "打了通电话.");
    }
    public void sendMessage(String name) {
        System.out.println("我给" + name + "发了条短信.");
    }
    public void playGame(String name) {
        System.out.println("我玩了局" + name + ".");
    }
}

该代码加载执行顺序为:首先将TelDemo.class和Tel.class文件加载到方法区,其中包含其成员变量和成员方法;main方法入栈

 执行Tel phone1=new Tel(); 此时便会执行上述的对象初始化过程。

 注意:类的方法区里存有类的全部信息(成员方法与成员变量),而堆中new出来的对象仅含成员变量,无成员方法;

成员变量和局部变量的区别:
    (1)在类中的位置不同
        成员变量:成员位置
        局部变量:方法内或者方法声明上
    (2)在内存中的位置不同
        成员变量:堆
        局部变量:栈
    (3)生命周期不同
        成员变量:随着对象产生而开始,随着对象的消亡而结束
        局部变量:随着方法的入栈而开始,随着方法的出栈而结束
    (4)初始化值不同
        成员变量:默认初始值
        局部变量:不赋值不能使用

匿名对象
    (1)没有名字的对象
        new Student()
    (2)应用场景
        a:调用方法,仅仅只调用一次的时候。
            new Student().study();
        b:可以作为实际参数传递。

  Static关键字:

  静态的意思是:可以修饰成员变量和成员方法,表示该成员属于整个类所有;

  静态的特点:

  A: 随着类的加载而加载
  B: 优先于对象而存在
  C: 被类的所有对象共享
  D: 通过类名直接调用,也可以通过对象名调用,推荐使用类名调用

  静态的内存图:

 

     静态的注意事项:

    a. 在静态方法中没有this关键字

    b.静态方法中只能访问静态的内容

 

   静态变量和成员变量的区别
        A:所属不同
            静态变量:类
            成员变量:对象
        B:内存位置不同
            静态变量:方法区的静态区
            成员变量:堆
        C:生命周期不同
            静态变量:随着类的加载而开始,类的消失而结束
            成员变量:随着对象的创建而开始,随着对象的消亡而结束
        D:调用不同
            静态变量:同过类名直接调用(推荐使用),通过对象调用(不推荐)。
            成员变量:只能通过对象调用
    (6)main方法是静态的
        public: 因为main()是被JVM调用, 所以访问权限得够大
        static: main()是程序的入口, 被调用的时候还没对象存在
        void:  将返回值返回给JVM是没有意义的
        main: 约定俗成的名字
        String[] args: 早期用来接收键盘录入的数据
         

 

代码块:
    (1)用{}括起来的代码。
    (2)分类:
        A: 局部代码块:
            限定变量的生命周期,及早释放内存空间,提高利用率

           {

              int a=3;

              System.out.println("a++");//该代码执行完后,变量a的内存将回收

           }
               

                         
        B: 构造代码块:
            将构造方法的最前面的相同内容抽取出来,放在构造代码块中,用于给对象进行初始化
            每次创建对象都会执行 。

class CodeBlockDemo1 {
    static {
        System.out.println("这是静态代码块");
    }
    
    // 构造代码块
    {
        System.out.println("开始构建对象...");
    }
    
    public CodeBlockDemo1() {
        //System.out.println("开始构建对象...");
    }
    
    public CodeBlockDemo1(int a) {
        // System.out.println("开始构建对象...");
        System.out.println("a=" + a);
    }
    // ...
    
    public static void main(String[] args) {
        /*// 局部代码块
        {
            int a = 10;
            System.out.println("a=" + a);
        }
        System.out.println("a=" + a);*/
        
        new CodeBlockDemo1();
        new CodeBlockDemo1(10);
    }
    // 这是静态代码块
    // 开始构建对象...
    // 开始构建对象...
    // a=10
}

//因为静态代码块在类被初始化时就会执行,所以先执行静态代码块;接着是构造代码块,因为构造代码块里的内容是从构造方法里提取出来的,所以每次创建对象时就会执行构造代码块里的内容。


 C: 静态代码块
            给类进行初始化
            随着类的加载而执行的,只执行一次
 D: 同步代码块(后面讲)
  (3)静态代码块,构造代码块,构造方法的顺序问题?
        静态代码块 > 构造代码块 > 构造方法  

     

  类的加载顺序总结:

静态区域(静态成员+静态块)在类的加载时完成;非静态成团变量只有在new一个对象时才完成初始化。

顺序如下:

  • 父类静态区域
  • 子类静态区域
  • 父类非静态成员
  • 父类构造方法
  • 子类非静态成团
  • 子类构造方法

 

 

继承:

1. 继承
    (1)把多个类中相同的成员给提取出来定义到一个独立的类中。然后让这多个类和该单独的类产生一个关系,使多个类中具备这个单独的类中定义的成员。
           这个关系叫继承。
    (2)Java中如何表示继承呢?格式是什么呢?
        A:用关键字extends表示
        B:格式:class 子类名 extends 父类名 {}
    (3)继承的好处:
        A:提高了代码的复用性
        B:提高了代码的维护性
        C:让类与类产生了一个关系,是多态的前提
    (4)继承的弊端:
        A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
            设计原则:低耦合,高内聚。
            耦合:类与类的关系
            内聚:自己完成某件事情的能力(责任)
        B:打破了封装性
    (5)Java中继承的特点
        A: Java只支持单继承,不支持多继承
        B: 但是支持多层继承      界门纲目科属种
    (6)继承的注意事项:
        A:子类不能继承父类的私有成员(私有成员是被子类隐式继承的,其实私有成员被继承了,但是在子类中不能访问。反射)
        B:子类不能继承父类的构造方法,但是可以通过super去访问
        C:不要为了部分功能而去继承。
    (7)什么时候使用继承呢?
        继承的原则:
            A类和B类如果是: is a
            is a的关系:
            Person:
                Student
                Teacher
    (8)Java继承中的成员关系
        A:成员变量
            a:子类的成员变量名称和父类中的成员变量名称不一样。
            b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢?
                子类的方法访问变量的查找顺序:
                首先找子类的局部变量
                再找子类的成员变量
                再找父类的成员变量

     
      

 B:构造方法
            a:子类的构造方法默认会去访问父类的无参构造方法
                目的:将在父类中定义的成员变量初始化。
            b:父类中如果没有无参构造方法,怎么办?
                子类通过super去明确调用带参构造
                子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造
                让父类提供无参构造
                this(...), super(...)只能在构造方法的第一条语句。

        C:成员方法
            a:子类的成员方法和父类中的成员方法签名不一样。
            b:子类的成员方法和父类中的成员方法签名一样,这个怎么访问呢?
                通过子类对象访问一个方法的查找顺序:
                查找子类的成员方法
                再查找父类的成员方法(没有就报错,不考虑父亲的父亲)
                    
    (9)两个面试题:
        A:Override和Overload的区别? Overload是否可以改变返回值类型?
            override: 子类重写父类的同名方法。要求子类的返回值类型要被父类兼容,方法名一样,参数列表一样。子类的访问权限不能比父类的小。
            overload:在同一个类中,方法名一样,但是参数列表不一样。与返回值类型无关
                如果在子类中定义了一个和父类同名的方法,但是参数列表不一样就会构成重载。
                如果在子类中定义了一个和父类同名的方法,但是参数列表一样,但是返回值类型不兼容,会报错。
        B:this和super的区别和各自的作用?
            this
            this.成员变量    super.成员变量 
            this(...)        super(...)
            this.成员方法()    super.成员方法()
    (10)数据初始化的面试题(了解)
        A:子类对象的初始化过程
        B:子父类的构造执行过程
            加载父类
            加载子类
            对父类进行初始化
            对子类进行初始化
        C:分层初始化

2 :final关键字
    (1)是最终的意思,可以修饰类,方法,变量。
    (2)特点:
        A:修饰类,表示这个类不能被继承(绝育手术)
        B:修饰变量,表示该变量使常量,它的值不能被修改
            基本数据类型:里面的值不能被修改
            引用数据类型:它的地址值不能被修改,指向同一个对象,但是对象的内容可以修改
            注意事项:
                被final的变量必须进行显示赋值
                只能被赋值一次,即使值相同。
        C:修饰方法,表示该方法不能被子类重写        

 

例题分析:

           

 

分析:首先JVM执行main方法,便将Test2类加载到方法区中进行初始化,要执行new Z()时,便准备初始化Z类,但由于Z类继承X类,所以 优先初始化X类,在X类中有static区域,所以先执行静态区域;然后回到z类,初始化的同时执行静态区域的内容;接着准备执行Y b=new Y()时就会加载Y类,至此所有类均初始化完毕。

output:

this is Static X
this is Static Z
this is constuction Y
this is y
this is constuction X
this is x
this is constuction Y
this is y
this is z
 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值