第三章笔记整理

面向对象是相对于面向过程来讲的,指的是把相关的数据和方法组织作为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。

面向过程到面向对象思想层面的转变:

面向过程关注的是执行的过程,面向对象关注的是具备功能的对象。

从面向过程到面向对象,是程序员思想上从执行者到指挥者的转变。

面向对象思想从概念上讲分为以下三种:OOA、OOD、OOP。

OOA:面向对象分析(Object Oriented Analysis)

OOD:面向对象设计(Object Oriented Design)

OOP:面向对象程序(Object Oriented Programming)

三大特征

封装性:所有的内容对外部不可见

继承性:将其他的功能继承下来继续发展

多态性:方法的重载本身就是一种多态性的体现

(面试)

封装:

1、私有化成员变量,使用private关键字修饰

2、提供公有的get/set方法,并在方法体中进行合理的判断

3、在构造方法中调用set方法进行合理的判断

封装的意义在于保护或者防止代码(数据)被我们无意中破坏,保护成员属性不让类以外的程序直接访问和修改。

创建对象的格式:类名 对象名 = new 类名();

对象的属性赋值:对象名.属性名 = 值;

栈存放的是基本数据类型的数据以及引用数据类型的引用。

例如:int a = 10;  Person p = new Person();  //10 p

栈的存取速度特别快(先进后出)。

堆存放的是类的对象。

堆内存与栈内存不同,优点在于我们创建对象时,不必关注堆内存中需要开辟多少存储空间,也不必关注内存占用的时长。

方法区存放的是类信息、静态的变量、常量和成员方法。 

方法区中包含了一个特殊的区域:常量池(存储的是使用static修饰的成员)。

PC寄存器存放的是当前正在执行的JVM指令的地址。

在java程序中,每一个线程启动时,都会创建一个PC寄存器。

本地方法栈指的是保存本地(native)方法的地址。

构造方法(构造器)

作用:用于对象初始化 

执行时机:在创建对象时,自动调用

特点:所有的java类中都会至少存在一个构造方法

如果一个类中没有明确的编写构造方法,则编译器会自动生成一个无参的构造方法,构造方法中没有任何的代码;如果自行编写了任意一个构造器,则编译器不会再自动生成无参的构造方法。

(面试)

一个类中定义的方法是允许重载的:

1、方法名称相同

2、参数列表长度不同或参数列表类型不同或参数的顺序不同

注意:方法的重载与返回值无关。

没有对象名称的对象就是匿名对象(匿名对象只能使用一次)。

在开发中为了避免出现逻辑错误(例如年龄:-30),我们建议对所有属性进行封装,并为其提供set/get方法进行设置和取得操作。

在java基础中,this关键字是一个重要的概念,使用this关键字可以完成以下的操作:

1、调用类中的属性

2、调用类中的方法或构造方法

3、表示当前的对象  this.(自动隐藏)name = name;

static表示“静态(只有一份)”的意思,可用来修饰成员变量和成员方法,主要作用是被static关键字修饰的方法或变量不需要依赖于对象来进行访问,只要类被加载就可以通过类名.的方式去进行访问;并且不会因为对象的多次创建,而在内存中建立多份数据。

(面试)

由于静态修饰的方法在被访问时,有可能对象还未创建,因此静态(隶属于类层级)不能访问非静态(隶属于对象层级),反之则可以。

在类中的成员代码块,我们称其为构造代码块,在每次对象创建时执行,执行在构造方法之前(无论用户调用哪一个构造方法来创建对象,构造代码块都必然会执行)。

在类中使用static修饰的成员代码块,我们称其为静态代码块,在类加载时执行,每次程序从启动到关闭,只会执行一次的代码块。

(面试)

构造方法、构造代码块和静态代码块的先后执行顺序:

静态代码块 > 构造代码块 > 构造方法

包的命名:com.公司名.项目名.模块名...(全部小写)

import 包名.类名;

单例设计模式:保证程序在内存中只有一个对象存在(被程序所共享)。

继承:java中只有单继承和多重继承(子→父→爷),没有多继承。

通过super构造方法可以访问父类的方法、属性和构造方法,调用super构造方法的代码,必须写在子类构造方法的第一行(与this的用法冲突,需分开)。

(面试)

重写规则(子继承父):

1、参数列表必须完全与被重写方法的参数列表相同

2、返回类型必须完全与被重写方法的返回类型相同

3、子类中的访问权限不能比父类中被重写方法的访问权限更低

4、父类的成员方法只能被它的子类重写

5、声明为static和private的方法不能被重写,但是能够再次的声明

object类是所有类的父类,如果一个类没有明确的继承某一个具体的类,则将默认继承object类。

(面试)

Java中重写(Override)与重载(Overload)的区别:

1.发生的位置

       重载:一个类中

       重写:子父类中

2.参数列表限制

       重载:必须不同的

       重写:必须相同的

3.返回值类型

       重载:与返回值无关

       重写:返回值类型必须一致

4.访问权限

       重载:与访问权限无关

       重写:子类的方法权限必须不能低于父类的方法权限

5.异常处理:

       重载:与异常无关

       重写:异常范围可以更小,但不能抛出新的异常

多态:父类的引用指向子类的对象。

判断某个对象是否为指定类的实例,可以使用instanceof关键字;此操作返回boolean类型的数据。

只声明而未实现的方法称为抽象方法(未实现指的是:没有{方法体}),抽象方法必须使用abstract关键字声明。

抽象类必须使用abstract  class声明,一个抽象类中可以没有抽象方法,但抽象方法必须写在抽象类或者接口中。

抽象类本身是不能直接进行实例化操作的,即:不能直接使用new关键字。

一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须重写抽象类中的全部抽象方法。

抽象类对子类具有强制性和约束性(模板设计模式)。

final(最终):用于修饰属性、变量;使变量成为常量,无法对其再次赋值。

局部变量只能赋值一次(可以先声明后赋值),成员属性必须在声明时赋值。

final修饰的类,不能被继承;修饰的方法,不能被子类重写。

(面试)

abstract(等着被继承)和private(私有化无法被继承)不能共存。

abstract(没有方法体,需要重写)和final(修饰之后不能被重写)不能共用。

abstract和static(可通过类名.的方式调用)不能同时出现。

全局常量(public static final)

常量的命名规范:由1个或多个单词组成,单词与单词之间必须使用下划线隔开,单词中所有的字母大写,例如:SQL_INSET。

如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口(interface),因为接口本身都是由全局常量和抽象方法组成,全局常量在编写时可以省略public static final关键字;抽象方法在编写时可以省略public abstract关键字。

如果一个接口要想使用,必须依靠子类;子类(如果不是抽象类的话)要实现接口中的所有抽象方法。

(面试)

抽象类和接口的区别:

1、定义抽象类的关键字是abstract class,而定义接口的关键字是interface

2、继承抽象类的关键字是extends,而实现接口的关键字是implements

3、继承抽象类支持单继承,而实现接口支持多实现

4、抽象类中可以有构造方法,而接口中不可以有构造方法

5、抽象类中可以有成员变量,而接口中只可以有全局常量

6、抽象类中可以有成员方法,而接口中只可以有抽象方法(Java8前的版本)

7、抽象类中增加方法时,子类可以不用重写,而接口中增加方法时,实现类需要重写(Java8前的版本)

8、从Java8开始增加了新特性,接口中允许出现非抽象方法和静态方法,但非抽象方法要使用default关键字修饰

9、从Java9开始增加了新特性,接口中允许出现私有方法

toString方法的作用是返回对象的字符串表示形式,Object类中的toString方法,返回对象的内存地址。当使用print或println语句时,程序会自动调用toString方法(建议重写)。

==如果是用于基本数据类型的比较,则比较的是具体的值,如果是用于引用数据类型(包装类型)的比较,则比较的是两个对象的地址。

equals方法,默认不重写的情况下比较的是两个对象的地址,方法重写后,则比较的是内容。

若需要比较两个对象某一属性的值是否相等,需要重写equals方法;与此同时,HashCode方法也需要重写(为了使结果保持一致)。

public boolean equals(object obj){

    //当调用对象和参数对象的地址相同时,则内容一定相同

    if(this == obj) return true;

    //当参数对象为空时,则内容一定不相同

    if(null == obj) return false;

    //若参数对象与调用的对象不一致时,则内容一定不相同

    if( !(obj instanceof Student) ) return false;

    //判断调用对象和参数对象的学号是否相等

    Student student = (Student)obj;

    return this.getId() == student.getId();

}

当String、Math、Integer、Double等包装类在使用equals方法时,就已经覆盖了object类的 equals方法,不再是地址的比较,而是内容的比较。

在java中,可以将一个类定义在一个方法或者另一个类里面,这样的类称为内部类。(了解即可)

广泛意义上的内部类一般来说包括这四种:

1、成员内部类   2、局部内部类   3、匿名内部类   4、静态内部类

成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和static成员)。

不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。

如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量       外部类.this.成员方法

外部类使用成员内部类

Outter outter = new Outter(); 外部类

Outter.Inner inner = outter.new Inner();内部类

局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

匿名内部类我们必须要继承一个父类或者实现一个接口,当然也只能继承一个父类或者实现一个接口。同时它没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用,当然这个引用是隐式的。

new 父类构造器(参数列表)  |  实现接口(){ //匿名内部类的类体部分 }

在使用匿名内部类的过程中,我们需要注意如下几点:

1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

2、匿名内部类中是不能定义构造函数的。

3、匿名内部类中不能存在任何的静态成员变量和静态方法。

4、匿名内部类为局部内部类,因此局部内部类的所有限制同样对匿名内部类生效。

5、匿名内部类不能是抽象的,它必须要实现继承类或者实现接口的所有抽象方法。

6、只能访问final类型的局部变量。

静态内部类是不需要依赖于外部类对象的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非静态成员变量或方法。

(了解)

请描述什么是内存溢出以及什么是内存泄漏?

内存溢出:装不下,溢出来了

内存泄漏:无法使用且不会被当作垃圾回收的内容

需要对内部类有深刻的认知:内部类的对象持有外部类对象的引用

垃圾回收器回收什么样的数据:没有引用的数据会被当作垃圾清理

外部类 x:100个方法  内部类 y:10个方法

Y y = null;

{  X x = new X();     //执行完毕当前{ }内容就会超过作用域被垃圾回收

       y = x.new Y();   }

         ↓

持有x但是无法使用,只能使用y的10个方法,从而造成内存泄漏

八种基本数据类型的包装类,可分为两种大的类型:

Number:Integer、Short、Long、Double、Float、Byte都是Number的子类,表示是一个数字。

Object:Character、Boolean都是Object的直接子类。

将一个基本数据类型变为包装类,这样的操作称为装箱操作。

将一个包装类变为基本数据类型,这样的操作称为拆箱操作。

(面试)

//-128~127自动装箱

Integer i1 = 127;//若将127改为128,结果为FTFT

Integer i2 = 127;

Integer i3 = new Integer(127);

Integer i4 = new Integer(127);

System.out.println(i1 == i2);          // T,比较地址

System.out.println(i1.equals(i2));  // T,比较内容

System.out.println(i3 == i4);          // F,比较地址

System.out.println(i3.equals(i4));  // T,比较内容

使用包装类还有一个优点在于:可以将一个字符串变为指定的基本数据类型,此操作一般在接收输入数据上使用较多。

String text = input.nextLine();

int x = Integer.parseInt(text);  //将字符串变为Integer类型并进行拆箱操作

(面试)

int ia = Integer.parseInt("12345");//实现字符串到整数的转换

System.out.println(ia);

String S1 = "" + ia;//实现整数到字符串的转换

System.out.println(S1);

int...nums表示可变参数,调用时可以传递0~n个数字;在方法的内部可变参数以数组的形式作为载体体现。

递推(1*2*3*4*5)使用for循环的方式

递归(!5)是指在方法的定义中调用方法本身,使用if语句判断

Object→Throwable(父类)→Error(错误)JVM发出只能尽量避免,无法代码处理

                       ↓

               Exception(异常,try-catch处理)

                       ↓                       ↓

                受检异常         非受检异常RuntimeException

     (必须明确抛出,飘红)      (运行时异常,不飘红)

异常是指在程序中导致程序中断运行的一种指令流,对异常进行处理的标准处理格式,如下:

格式一

try{

    // 有可能发生异常的代码段

}catch(异常类型1 对象名1){

    // 异常的处理操作

}catch(异常类型2 对象名2){

    // 异常的处理操作

} finally{

    // 异常的统一出口 

}

格式二

try{

    // 有可能发生异常的代码段

}catch(异常类型1 | 异常类型2 对象名){

    // 异常的处理操作

}

格式三

try{

    // 有可能发生异常的代码段

}catch(Exception 对象名){

    // 异常的处理操作

    // 处理所有类型的异常,扩大范围

}

在进行异常的处理之后,异常的处理格式中还有一个finally语句,此语句将作为异常的统一出口,不管是否产生了异常,最终都要执行此段代码。

常见的异常类型:

ArithmeticException 算数异常    NullPointerException 空指针异常

ArrayIndexOutOfBoundsException 数组下标越界异常  

ClassNotFoundException 未找到相应类异常    IOException 输入输出异常

ClassCastException 类型转换异常     SQLException 操作数据库异常

throws关键字主要在方法的声明上使用,表示方法中不处理异常,交给调用处处理。

throw关键字表示在程序中人为的抛出一个异常,因为从异常处理机制来看,所有的异常一旦产生之后,实际上抛出的就是一个异常类的实例化对象,那么此对象也可以由throw直接抛出。

代码:throw new Exception("抛着玩的。") ;

问:异常是否抛出去,应该站在哪个角度思考?

答:如果是因为传参而导致异常,应通过throws将其抛出。

只要是RuntimeException的子类,则表示程序在操作的时候可以不必使用try-catch进行处理,如果有异常发生,则由JVM进行处理。

(面试)

问:try-catch-finally中哪个部分可以省略? 

答:catch和finally可以省略其中一个,但是不能同时省略。

注意:格式上允许省略catch块, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写。

(面试)

问:try-catch-finally中,如果catch中return了,finally 还会执行吗?

答:finally中的代码会执行。

执行流程:

1、先计算返回值,并将返回值存储起来,等待返回

2、执行finally代码块

3、将之前存储的返回值,返回出去

注意:如果返回的是变量,返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变。

(面试)

问:try、catch、finally中,如果都包含return代码,返回值以谁的为最终返回值?

答:finally中的返回值为最终返回值。

(面试)

问:如果try或catch通过System.exit(0);退出程序,finally块还会执行吗?

答:不执行。

System.exit(0);表示停止JVM,虚拟机停止,则所有java代码停止。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值