黑马程序员--java技术--面向对象
来源:互联网 发布:双11淘宝电脑打折么 编辑:程序博客网 时间:2024/05/25 23:58
- ------- android培训、java培训、期待与您交流! ----------
- 面向对象和面向过程都是一种思想
- 面向对象时基于面向过程的
以后开发其实就是找对象使用,没有对象,就创建一个对象
找对象--建立对象--使用对象--维护对象的关系
类和对象的关系
类:对现实生活中事物的描述
对象:就是这类事物,实实在在的个体
面试常用:怎么理解面向对象?面向对象的举例(买电脑、软件公司招人)
成员变量和局部变量
作用范围
成员变量:作用于整个类中
局部变量:作用于函数或者语句中
在内存中的位置
成员变量:在堆内存中,因为对象的存在,才在内存中存在
局部变量:存在栈内存中。
匿名对象
匿名对象使用方式一:当对对象的方法只调用一次时,可以使用匿名对象来完成,这样写比较简化。
· 如果对一个对象进行多个成员调用,必须给这个对象起个名字
匿名对象使用方式二:可以将匿名对象作为实际参数进行传递。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式
优点:
1、将变化隔离
2、便于使用
3、提高复用性
4、提高安全性
封装原则:
1、将不需要对外提供的内容都隐藏起来
2、把属性都隐藏,提供公共方法对其访问
private:私有,权限修饰符:用于修饰类中的成员(成员变量,成员函数)
私有修饰的成员只在本类中能被访问
构造函数
特点:
1、函数名与类名相同
2、不用定义返回值类型
3、不可以写return语句
作用:给对象进行初始化
注意:
1、默认构造函数的特点
2、多个构造函数是以重载的形式存在的
构造函数:在对象一建立就运行,给对象初始化。
一个对象建立,构造函数只运行一次
一般函数:对象调用才执行,给对象添加对象具备的功能
一般函数可以运行多次
什么时候定义构造函数呢?
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中
构造代码块
格式
{执行语句}
作用:给对象进行初始化对象一建立就进行,而且优先于构造函数执行
构造代码块:给所有对象进行初始化
构造函数:给对应的对象进行初始化
构造代码块中定义的是不同对象共性的初始化内容this:本类的对象,就是它所在函数所属对象的引用
this的应用:
1、用于区分同名变量,成员变量与局部变量同名(当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象,哪个对象在调用this所在的函数,this就代表哪个对象)
2、用于构造函数间调用
3、当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
但凡本类功能内部使用了本类的对象,都用this表示。
this语句:构造函数之间的互相调用只能用this语句
this语句:只能定义在构造函数的第一行,因为初始化要先执行。
静态:static
用法:是一个修饰符,用于修饰成员(成员变量,成员函数)
当成员被静态修饰后,就多了一个新的调用方式,除了能被对象调用,还可以直接被类名调用,类名.静态成员
static特点:
1、随着类的加载而加载,消失而消失,说明它的生命周期最长
2、优先于对象存在,静态是先存在,对象是后存在的
3、被所有对象所共享,节约内存空间4、可以直接被类名调用
实例变量和类变量的区别:
1、存放位置:
类变量随着类的加载而存在于方法区中
实例变量随着对象的建立而存在于堆内存中
2、生命周期:
类变量最长,随着类的消失而消失
实例变量生命周期随着对象的消失而消失
静态使用注意事项:
1、静态方法只能访问静态成员,非静态方法可以访问静态和非静态成员
2、静态方法中不可以定义this,super关键字,因为静态优先于对象存在。
静态的利弊
利:1、对对象的共享数据进行单独空间的存储,节省空间。
2、可以直接被类名调用
弊:1、生命周期过长
2、访问有局限性(只能访问静态)
主函数:是一个特殊的函数,作为程序的入口,可以被jvm调用
public static void main(String[ ] args){ }
定义:
public:代表该函数访问权限是最大的
static:代表主函数随着类的加载就已经存在了
void:主函数没有具体的返回值
main:不是关键字,但是是一个特殊的单词,可以被jvm识别
(String[] arr):函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组
jvm在调用主函数时,传入的是new String[0]
什么时候使用静态?
两个方面思考:
静态修饰的内容有成员变量和函数
什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态修饰
对象中的特有数据要定义成非静态存在于堆内存中
什么时候定义静态函数呢?
当功能内没有访问到非静态数据(对象的特有数据)
static的应用:工具类
帮助文档的制作
静态代码块
static{执行语句}
特点:随着类的加载而执行,只执行一次,并优先于主函数
用于给类进行初始化
设计模式:解决某一类问题最行之有效的方法
java中23种设计模式:单例设计模式:希望一个类在内存只存在一个对象,想要保证对象唯一。
1、为了避免其他程序过多建立该类对象,先禁止其他程序建立该对象
2、为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象
3、为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三部怎么用代码体现:
1、将构造函数私有化
2、在类中建立一个本类对象
3、提供一个方法可以获取到该对象
对于事物该怎么描述还怎么描述
当需要该事物的对象保证在内存中唯一时,就将以上的三部加上即可
单例设计模式的两种:
饿汉式:先初始化对象
class single {private single(){}private static single s = new single();public static single getInstance(){return s;}}懒汉式:方法被调用时,才初始化,也叫对象的延时加载(面试常考)
class single2{private single2(){}private static single2 s = null;public static single2 getInstance(){if(s==null){synchronized(single2.class){if(s==null)s = new single2();}}return s;}}
继承:
1、提高了代码的复用性
2、让类与类之间产生了关系。有了这个关系,才有了多态的特性。
注意:千万不要为了获取其他类的功能,简化代码而继承
java语言中:java只支持单继承,不支持多继承,但是java保留了这种机制,并用另一种体现形式来完成表示,叫多实现
因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不确定时,子类对象不确定要运行哪一个。
java支持多层继承。也就是一个继承体系
如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系中父类的描述,因为父类中定义的是该体系中的共性功能。
通过了解共性功能就可以知道该体系的基本功能。
这个体系已经可以基本使用了
在具体调用时,要创建最子类的对象。
一是有可能父类不能创建对象,二是创建子类对象可以使用更多的功能,包括共有的和特有的
一句话:查阅父类功能,创建子类对象使用功能。
子父类出现后,类成员的特点:
类中成员:
1、变量
2、函数
3、构造函数
1、变量
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this,子类要访问父类中的同名变量,用super
super的使用和this的使用几乎一致。
this代表子类对象的引用
super代表父类对象的引用
2、函数
当子类出现和父类一模一样的函数时
当子类对象调用该函数,会运行子类函数的内容
如同父类的函数被覆盖一样。
这种情况是函数的另一个特性:覆盖(重写),用于扩展
当子类继承了父类,沿袭了父类的功能到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容
子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
静态只能覆盖静态
重载:只看同名函数的参数列表
覆盖:子父类方法要一模一样。
3、子父类中的构造函数。
在对子类对象进行初始化时,父类的构造函数也会运行
因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数,
为什么子类一定要访问父类中的构造函数
父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对对象初始化时,要先访问父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定
注意:super语句一定定义在子类构造函数的第一行。
结论:子类的所有的构造函数,默认都会访问父类中空参数的构造函数,因为每一个子类构造函数的第一行都有一句隐式super()
当父类中没有空参数的构造函数时,子类必须手动通过super来指定要访问的构造函数
final:最终。一个修饰符
1、可以修饰类、函数、变量
2、被final修饰的类不可以被继承,为了避免被子类复写功能。
3、被final修饰的方式不可以被复写
4、被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,又可以修饰局部变量
当在描述事物时,一些数据的出现值是固定的,那么为了增强阅读性,都给这些值起个名字,方便阅读。而这个值不需要改变,所以加上final修饰
常量:所有字母都大写,如果由多个单词组成,单子间用通过_连接
5、内部类定义在类中的局部位置上时只能访问该局部被final修饰的局部变量
abstract
当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取,只抽取功能定义,不抽取功能主题
抽象类的特点:
1、抽象方法一定定义在抽象类中
2、抽象方法和抽象类都必须被abstract关键字修饰
3、抽象类不可以用new创建对象,因为调用抽象方法没意义
4、抽象类中的方法要被使用,必须由子类复写其所有的抽象方法后,建立子类对象调用
如果子类只覆盖了部分抽象方法,该子类还是一个抽象类
抽象类比一般类多了个抽象函数
抽象类不可以实例化,是为了不让该类建立对象
接口:初期可以认为是一个特殊的抽象类
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示
class:用于定义类
interface:用于定义接口
接口定义时,格式:
1、常见定义:常量,抽象方法
2、接口中的成员都有固定修饰符
常量:public static final
方法:public abstract
接口中的成员都是public的
接口是不可以创建对象的,因为所有抽象方法
需要被子类实现,子类对接口中的抽象方法全都被覆盖后,子类才可以实现化,否则子类是个抽象类
接口可以被类多实现,也是对多继承的转换形式
多态:事物存在的多种体现形态
1、多态的体现
父类的引用指向了自己的子类对象
2、多态的前提
必须是类与类之间有关系,继承或者实现
3、多态的好处
多态的出现提高了程序的扩展性
存在覆盖
4、多态的弊端
只能使用父类的引用访问父类中的成员
5、多态的应用
6、多态的特点
在多态中,成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
多态中成员函数的特点:
结论: 编译看左边,运行看右边
多态中成员变量的特点:
结论: 无论编译或运行,都参考左边
多态中静态成员函数的特点:
结论: 无论编译和运行,都参考左边
Object:是所有对象的直接后者间接父类,超类
该类中定义的肯定是所有对象都具备的功能
Object类中已经提供了对对象是否相同的比较方法
如果自定义类中也有比较相同的功能,没有必要重新定义
只要沿袭父类中的功能,建立自己特有比较内容即可。覆盖
内部类的访问规则:
1、内部类可以直接访问外部类中的成员,包括私有
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this
2、外部类要访问内部类,必须建立内部类对象
访问格式:当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象
格式:外部类名.内部类名 变量名=外部类对象.内部类对象;
Outer.Inner in=new Outer().new Inner();
2、当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他内中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的
当外部类中的静态方法访问内部类时,内部类必须是static的
内部类定义在局部时:
1、不可以被成员修饰符修饰
2、可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问它所在的局部中的变量,只能访问被final修饰的成员变量
匿名内部类:
1、匿名内部类其实就是内部类的简写格式
2、定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口
3、匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4、其实匿名内部类就是一个匿名子类对象,而且这个对象有点儿胖。可以理解为带内容的对象
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象
其实就是java对不正常情况进行描述后的对象体现
对于问题的划分:两种:一种是严重的问题,一种非严重的问题
对于严重的,java通过Error类进行描述
一般不编写针对性的代码对其进行处理
对于非严重的,java通过Exception类进行描述
对于Exception可以使用针对性的处理方式进行处理
声明异常时,建议声明更为具体的异常,
继承Exception的原因:
异常体系都有一个特点,异常类和异常对象都被抛出
他们都具备可抛性,可抛性是Throwable这个体系中独有特点
只有这个体系中的类和对象才可以被throws和throw操作
后面跟的是异常类,可以跟多个,用逗号隔开
throw:使用在函数内
后面跟异常对象
RuntimeException 特殊的子类异常
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过
如果在函数上声明了该异常。调用者可以不用进行处理,编译一样通过
自定义异常时:如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException
异常分两种:
1、编译时被检测的异常
2、编译时不被检测的异常(运行时异常。RuntimeException及其子类)
catch:用于处理异常
finally:存放一定会被执行的代码
异常:对问题的描述,将问题进行对象的封装
异常体系:
Throwable
|--Error
|--Exception
|--RuntimeException
异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性,也就是可以被throw和throws关键字操作,只有异常体系具备这个特点
当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则都编译失败。
RuntimeException除外,抛出RuntimeException异常可以不用声明
如果函数声明了异常,调用者需要进行处理,处理方法可以throws也可以try
异常有两种:
编译时被检测异常
该异常在编译时,如果没有处理(没有抛也没有try),编译失败
该异常被标识,代表这可以被处理
运行时异常
在编译时,不需要处理,编译器不检查
该异常发生,建议不处理,让程序停止,需要对代码进行修正
异常处理的语句:
try { 需要被检测的代码 }
catch { 处理异常的代码 }
finally { 一定会执行的代码 }
三种结合格式:
try{ }
catch{ }
finally{ }
try{ }
catch{ }
try{ }
finally{ }
finally:关闭资源代码,因为资源必须释放
只有当执行到System.exit(0);时finally不会执行
自定义异常:
定义类继承Exception或者RuntimeException
1、为了让该类自定义类具备可抛性
2、让该类具备操作异常的共性方法
当要定义自定义异常的信息时,可以使用父类已经定义好的功能
异常信息传递给父类的构造函数
按照java的面向对象思想,将程序中出现的特有问题进行封装
异常的好处:
1、将问题进行封装
2、将正常流程代码和问题处理代码相分离,方便阅读
异常的处理原则:
1、处理方式有两种:try或者throws
2、调用到抛出异常的功能时,抛几个就处理几个
一个try对应多个catch
3、多个catch,父类的catch放到最下面
4、catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句
不要不写
当捕获到的异常,本功能处理不了时,可以继续在catch中抛出(嵌套抛)
如果该异常处理不了,但并不属于该功能出现的异常
可以将异常转换后,在抛出和该功能相关的异常
如果异常可以处理,需要将异常产生和本功能相关的问题提供出去,让调用者知道,并处理。也可以将捕获异常处理后,转换新的异常。
异常注意事项:
在子父类覆盖时:
1、子类抛出的异常必须是父类异常的子类或者子集
2、如果父类或者接口没有异常抛出时,子类覆盖出现异常只能try,不能抛
包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰
不用包中的子类还可以直接访问父类中被protected权限修饰的成员
包与包之间可以使用的权限只有两种,public protected
publicprotecteddefault private同一个类中ok ok ok ok 同一个包中 ok okok 子类okok 不同包中ok
import:导入包中的类,简化类名的书写
面向对象
1、面向对象思想:
(1)概述:面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象,
强调具备功能的对象;
(2)思想特点:
A:是符合人们思考习惯的一种思想;
B:将复杂的事情简单化了;
C:将程序员从执行者变成了指挥者;
比如我要达到某种结果,我就寻找能帮我达到该结果的功能的对象,如我要洗衣服我就买洗衣机,
至于怎么洗我不管。
(3)特征:
封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式
继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义
这些属性和行为,只要继承那个类即可。
多态: 一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象
2、类和对象:
类:对现实世界中某类事物的描述,是抽象的,概念上的定义。
对象:事物具体存在的个体。
3:成员变量和局部变量的区别(重点)
(1)作用域
成员变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
(2)存储位置
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。
当方法调用完,或者语句结束后,就自动释放。
(3)初始值
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
4、匿名对象
(1)匿名对象就是没有名字的对象。是对象的一种简写形式。
(2)应用场景
A:只调用一次类中的方法。
B:可以作为实际参数在方法传递中使用
5、封装:
指隐藏对象的属性和实现细节,仅对外提供公共访问方式;比如电脑机箱、笔记本等
好处:
将变化隔离;
方便使用;
提高复用性;
提高安全性
6、关键字private:封装在代码中的体现
(1)私有的意思,权限修饰符
(2)用来修饰成员变量和成员函数
(3)用private修饰的成员只在本类中有效
(4)私有是封装的一种体现
7、构造方法:
(1)特点:
方法名与类名相同
没有返回类型
没有返回值
(2)作用:构造函数是用于创建对象,并对其进行初始化赋值,对象一建立就自动调用相对应的构造函数,
(3)构造方法的注意事项:
A:如果一个自定义类没有构造方法,系统会默认给出一个无参构造方法。
B:如果一个自定义类提供了构造方法,那么,系统将不再给出无参构造方法。
这个时候,你可以不使用无参构造方法。
如果你想使用,那么,就必须手动给出无参构造方法。
建议:一般情况下,我们的自定义类都要手动给出无参构造方法。
(4)构造方法和成员方法的区别
A:格式区别
构造方法和类名相同,并且没有返回类型,也没有返回值。
普通成员方法可以任意起名,必须有返回类型,可以没有返回值。
B:作用区别
构造方法用于创建对象,并进行初始化值。
普通成员方法是用于完成特定功能的。
C:调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
普通成员方法是由创建好的对象调用,可以调用多次
8、构造代码块:
(1)作用:给对象进行初始化,对象一建立就执行,而且优先于构造函数执行
(2)构造代码块和构造函数的区别:
构造代码块是给所有不同对象的共性进行统一初始化
构造函数是给对应的对象进行初始化
9、this关键字
(1)this关键字代表本类对象的一个引用,谁调用this所在的方法,this就代表谁
(2)this的使用场景
A:用于区分同名成员变量和局部变量;
B:在定义函数时,该函数内部要用到调用该函数的对象时,因为此时对象还没建立,故this代表此对象
B:构造函数间调用
**这个时候,this(参数)必须作为第一条语句存在。
10、Person p = new Person();在内存中做了哪些事情。
(1)将Person.class文件加载进内存中。
(2)如果p定义在主方法中,那么,就会在栈空间开辟一个变量空间p。
(3)在堆内存给对象分配空间。
(4)对对象中的成员进行默认初始化。
(5)对对象中的成员进行显示初始化。
(6)调用构造代码块对对象进行初始化。(如果没有就不执行)
(7)调用构造方法对对象进行初始化。对象初始化完毕。
(8)将对象的内存地址赋值给p变量,让p变量指向该对象。
11、static关键字:
(1)静态的意思,用来修饰成员变量和成员函数
(2)静态的特点:
随着类的加载而加载
优先于对象存在
对所有对象共享
可以被类名直接调用
(3)静态的注意事项
A:静态方法只能访问静态成员
为什么:因为静态的内容是随着类的加载而加载,它是先进内存的。
B:静态方法中不能使用this,super关键字
C:主方法是静态的
public static void main(String[] args)
public:公共的意思,是最大权限修饰符。
static:由于jvm调用main方法的时候,没有创建对象。
只能通过类名调用。所以,main必须用static修饰。
void:由于main方法是被jvm调用,不需要返回值。用void修饰。
main:main是主要的意思,所以jvm采用了这个名字。是程序的入口。
String[]:字符串数组
args:数组名
在运行的时候,通过java命令给args数组赋值。
格式:java MainTest hello world itcast
(4)静态变量和成员变量的区别
A:调用方式
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。
这个变量属于类。
成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。
B:存储位置
静态变量存储在方法区长中的静态区。
成员变量存储在堆内存。
C:生命周期
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
成员变量随着对象的创建而存在,随着对象的消失而消失。
D:与对象的相关性
静态变量是所有对象共享的数据。
成员变量是每个对象所特有的数据。
(5)静态的优点和弊端
优点:
对对象的共享数据进行单独空间的存储,节省内存,没有必要每个对象都存储一份
可直接被类名调用
弊端:
生命周期过长,随着类的消失而消失
访问出现权限,即静态虽好但只能访问静态
(6)什么使用使用静态呢?
A:当所有对象共享某个数据的时候,就把这个成员变量定义为静态修饰的。
B:当某个方法没有访问该类中的非静态成员,就可以把这个方法定义为静态修饰。
静态的生命周期比较长,所以一般不推荐使用。
(7)静态代码块
A:它只执行一次,它比main还先执行。
B:执行顺序
静态代码块--构造代码块--构造方法
12、制作API(次重点)
API(全拼):Application Program Interface 应用程序编程接口。
(1)类中的内容需要用文档注释。
(2)使用JDK\bin目录下的javadoc工具。
格式:javadoc -d 目录 -author -version ArrayTool.java
13、单例设计模式:
(1)设计模式:
解决某类问题行之有效的方法,是一种思想,是规律的总结
(2)用来保证某个类在内存中只有一个对象
(3)保证唯一性的思想及步骤
**为了避免其他程序建立该类对象,先禁止其他程序建立该类对象,即将构造函数私有化
**为了其他程序访问到该类对象,须在本类中创建一个该类私有对象
**为了方便其他程序访问到该类对象,可对外提供一个公共访问方式
比如API中的Runtime类就是单例设计模式。
(4)单例设计模式的两种方式
A:饿汉式 当类加载的时候,就创建对象。
class Student
{
private Student(){}
private static final Student s = new Student();
public static Student getInstance()
{
return s;
}
}
B:懒汉式 当使用的使用,才去创建对象。
class Student
{
private Student(){}
private static final Student s = null;
public static Student getInstance()
{
if(s==null)
{
//线程1就进来了,线程2就进来了。
s = new Student();
}
return s;
}
}
饿汉式和懒汉式的区别:
**
饿汉式是类一加载进内存就创建好了对象;
懒汉式则是类才加载进内存的时候,对象还没有存在,只有调用了getInstance()方法时,
对象才开始创建。
**
懒汉式是延迟加载,如果多个线程同时操作懒汉式时就有可能出现线程安全问题,解决线程安全问题
可以加同步来解决。但是加了同步之后,每一次都要比较锁,效率就变慢了,
所以可以加双重判断来提高程序效率。
注:开发常用饿汉式,因为饿汉式简单安全。懒汉式多线程的时候容易发生问题
14、Math类的使用(重点)
(1)数学操作类:该类没有构造函数,方法均为静态的
(2)掌握内容
A:成员变量
**E:比任何其他值都更接近e(即自然对数的底数)的double值。
**PI:比任何其他值都更接近pi(即圆的周长与直径之比)的double值。
B:成员方法
**static double abs(double a)
返回 double 值的绝对值。返回绝对值
**static double ceil(double a)
返回最小的(最接近负无穷大)double 值,该值大于等于参数,并等于某个整数。
**static double floor(double a)
返回最大的(最接近正无穷大)double 值,该值小于等于参数,并等于某个整数。
**max:返回两个值中较大的那个
**min:返回两个值中较小的那个
**static long round(double a) 返回最接近参数的 long。
static int round(float a) 返回最接近参数的 int。
**static double random()
返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
**static double pow(double a, double b)
返回第一个参数的第二个参数次幂的值。
**static double sqrt(double a)
返回正确舍入的 double 值的正平方根。
15、Random类的使用(重点)
(1)产生随机数的类
(2)掌握内容
A:构造方法
**Random() 创建一个新的随机数生成器。
**Random(long seed) 使用单个 long 种子创建一个新的随机数生成器。
B:成员方法
**int nextInt() 返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
**int nextInt(int n) 返回一个伪随机数,它是取自此随机数生成器序列的、
在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
16、Scanner类的使用
(1)可以获取从键盘的输入数据
(2)掌握内容
构造方法:
Scanner(InputStream source) 构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。
如:Scanner sc = new Scanner(System.in);
方法摘要
sc.nextInt();获取整型数据
sc.nextLine();获取字符串数据
17、继承(重点)
(1)把很多类的相同特征和行为进行抽取,用一个类来描述。让多个类和这个类产生一个关系。
这样的话,多个类就可以省略很多代码。这个关系就是继承。java中用extends关键字表示。
(2)继承的体系结构
A:多个具体的对象,不断的向上抽取共享的内容,最终形成了一个体系。这个体系叫做继承体系。
B:继承体系的学习和使用原则
**学习顶层的内容。因为他是整个体系的共性内容。
**创建子类使用。也就是使用底层的具体对象。
(3)继承的特点:
A:java中只能单继承,没有多继承。
B:java可以有多重(层)继承。
(4)继承的好处:
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
(5)子父类中的成员关系
A:成员变量
在子类方法中使用一个变量时:
首先,在方法的局部变量中找这个变量,有则使用。
否则,在本类中找成员变量,有则使用。
否则,在父类中找成员变量,有则使用。
否则,报错。
B:成员方法
用子类对象使用一个方法时。
首先,在子类中找这个方法,有则使用。
否则,在父类中找这个方法,有则使用。
否则,报错。
重写和重载的区别?
重载:在同一类中。方法名相同,参数列表不同。重载可以改变返回类型。
重写:在不同类中(子父类中)。
方法声明相同(返回类型,方法名,参数列表均相同)。
重写需要注意:
**子类方法的访问权限要大于等于父类方法的访问权限。
**静态只能重写静态。但是这种情况一般不会出现。
构造方法
**子类的实例化过程
***子类创建对象时,会先去创建父类的对象。
默认是去调用父类的无参构造方法。
***子类构造方法中,第一行默认是super()
***为什么子类中第一行会默认有super()
因为他继承父类的成员使用,使用前这些成员必须初始化,
而他们是父类的成员,所以,必须通过父类进行初始化。
所以,会先创建一个父类的对象。
**当父类没有无参构造方法时
必须使用this或者super调用其他的构造方法。
(6)this和super的区别
this:代表本类对象的引用。
super:代表父类的存储空间。
18、final关键字(重点)
(1)最终的意思,可以用于修饰类,方法,变量。
(2)final修饰的类不能被继承。
final修饰的方法不能被重写。
final修饰的变量是一个常量。只能被赋值一次。
内部类只能访问被final修饰的局部变量。
19、抽象类(重点)
(1)多个类有相同的方法声明,但是方法体不一样。这个时候,我们考虑把方法声明进行抽取。
让子类继承后,自己去实现方法体。没有方法体的方法,我们需要用抽象标志下。
抽象的关键字是:abstract。
(2)抽象类:
该方法称为抽象方法,包含抽象方法的类就是抽象类。
(3)抽象类的特点:
A:抽象类和抽象方法都要用abstract进行修饰
B:抽象类不能被实例化
C:抽象类中不一定有抽象方法,但是,有抽象方法的类一定是抽象类。
(4)抽象类中数据的特点
A:成员变量
抽象类中可以有变量,也可以有常量。
B:成员方法
抽象类中可以有抽象方法,也可以有非抽象方法。
C:构造方法
抽象类是一个类,所以,它有构造方法。
虽然本身不能实例化。但是可以给子类实例化使用。
(5)抽象类中的问题
A:抽象类中是否有构造方法?能不能被实例化?如果不能,为什么有构造方法?
抽象类有构造方法。
抽象类不能被实例化。
抽象类中的构造方法供子类实例化调用。
B:抽象关键字abstract不可以和哪些关键字共存?
**private:
私有内容子类继承不到,所以,不能重写。
但是abstract修饰的方法,要求被重写。两者冲突。
**final
final修饰的方法不能被重写。
而abstract修饰的方法,要求被重写。两者冲突。
**static
假如一个抽象方法能通过static修饰,那么这个方法,就可以直接通过类名调用。
而抽象方法是没有方法体的,这样的调用无意义。所以,不能用static修饰。
C:抽象类中可不可以没有抽象方法?如果可以,这样的类有什么用吗?
抽象类可以没有抽象方法。
抽象类中没有抽象方法的作用,只是为了不让别的类建立该抽象类对象。这个在awt中有体现。
20、接口interface
(1)当一个类中的方法都是抽象的时候,java提供了另一种表示方式,叫接口。
用interface关键字表示。类与接口关系用implements表示。
(2)接口的成员特点
A:成员变量
是常量,默认修饰 public static final
B:成员方法
都是抽象的,默认修饰 public abstract
(3)关系
A:类与类的关系
是继承关系。类与类只能单继承,可以多重继承。
B:类和接口的关系
是实现关系。类可以多实现接口。
类在继承一个类的同时,可以实现多个接口。
C:接口和接口的关系
是继承关系。接口可以多继承接口。
(4)接口的特点
A:是对外暴露的规则
B:是功能的扩展
C:接口的出现降低耦合性。
耦合(类与类之间的关系)
内聚(类完成功能的能力)
编程规范:低耦合,高内聚。
D:接口可以多实现。如:CPU和主板、笔记本的USB插口、插座
(5)接口和抽象类的区别
A:抽象类只能被单继承
接口可以多实现,接口的出现避免了多继承的局限性。
B:抽象类中的数据特点:
成员变量:可以是变量,也可以是常量
成员方法:可以是抽象方法,也可以是非抽象方法
构造方法:有构造方法
接口中的数据特点:
成员变量:是常量。默认修饰 public static final
成员方法:都是抽象方法。都有默认修饰 public abstract
构造方法:没有构造方法
C:抽象类中定义的是继承体系中的共性功能。
接口中定义的是继承体系中的扩展功能。
D:抽象类被继承是"is a"关系:xx是yy的一种
接口被实现是"like a"关系:xx像yy的一种
21、多态:
(1)同一个对象,在程序不同时刻的多种运行状态。举例:动物,狗是狗,狗是动物。水(气态,液态,固态)
(2)多态前提
A:存在着继承或者实现关系
B:有方法的重写
C:父类(接口)引用指向子类(实现)对象
(3)多态的好处和弊端:
好处:多态的存在提高了程序的扩展性和后期可维护性
弊端:虽然可以预先使用,但是只能访问父类中已有的功能,运行的是后期子类的功能内容。
不能预先使用子类中定义的特有功能。
(4)多态中对象调用成员的特点
Fu f = new Zi();
A:成员变量
编译看左边,运行看左边
B:成员方法
编译看左边,运行看右边
C:静态方法
编译看左边,运行看左边
(5)多态的思想
指挥同一批对象做事情。举例:带兵打仗,下课等。
22、instanceof关键字
A:用于判断某个对象是否是某种类型。
B:格式
对象名 instanceof 子类(实现)名
23、Object类:
(1)是所有类的根类,超类。
java中提供的类以及我们自定义的类都直接或者间接的继承自Object类。
(2)Object类中的方法
A:void finalize()
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
B:Class getClass()
获取对象的字节码文件的描述类,后面再讲反射的时候还会在说这个类。
String name = s.getClass().getName();
C:int hashCode()
获取对象的哈希值。其实就是对象的内存地址值十进制表示
D:String toString()
返回对象的字符串表示。
表示格式:
getClass().getName()+"@"+Integer.toHexString(hashCode());
一般我们输出对象名的时候,其实底层调用的就是该对象的toString()方法。
这种返回没有意义,所以,我们会重写这个方法,显示类的成员变量信息。
E:boolean equals(Object obj)
用于比较两个对象的地址值是否相同。
我们获取对象后,比较它的地址值意义不大。所以也会对这个方法进行重写。
重写要完成什么功能,是根据需求定的。
(3)==和equals的用法:
A:==怎么用?
**可以用于比较基本数据类型,比较的就是基本数据类型的值是否相等。
**可以用于比较引用数据类型,比较的是对象的地址值是否相等。
B:equals怎么用?
equals只能用于比较引用数据类型的。
**Object提供的equals是用于比较对象地址值是否相同。
**自定义类中,如果重写了equals方法,那么就是按照你自己的需求来比较的。
24、package关键字
(1)包:其实就是文件夹。用于区分不同包下相同的类名。
(2)好处:
A:对类文件进行分类管理。
B:给类提供了多层命名空间
aaa.Demo
bbb.Demo
C:写在程序文件的第一行。
D:包也是一种封装形式。
25、import关键字
(1)导入包的关键字
(2)格式:
import 包名;
(3)注意:
A:一个程序文件中只有一个package,可以有多个import。
B:用来导包中的类,不导入包中的包。
C:通常写import mypack.Demo,明确自己使用的类。
(4)关键字的顺序
类,包,导包这些关键的顺序。
包 -- > 到包 -- > 类
26、不同修饰符可以修饰哪些内容
本类中 同一个包中 不同包中的子类中 不同包中
private OK
默认 OKOk
protected OK Ok OK
public OK Ok OK Ok
类 构造方法成员变量成员方法
private OK OK OK
默认 OkOkOkOK
protected OK OK Ok
public OkOkOKOK
static OK Ok
final OkOKOK
abstract Ok OK
一般格式:
成员变量:
权限修饰符+static/final+数据类型+成员变量名
public static final int NUM = 10;
成员方法:
权限修饰符+static/final/abstract+返回类型+方法名
27、内部类(次重点)
(1)把一个类定义在某个类中的,这个类就被称为内部类,内置类,嵌套类。
(2)访问特点:
A:内部类可以直接访问外部类中的成员,因为内部类持有外部类的引用,
格式为:外部类名.this
B:外部类要想访问内部类的成员,必须创建对象访问。
(3)内部类的访问格式:
A:当内部类定义在外部类的成员位置,而且非私有,则可以在其他外部类中直接建立内部类对象
格式:外部类名.内部类名 变量名 = new 外部类对象.内部类对象
如:Outer.Inner in = new Outer().new Inner()
B:当内部类在外部类成员位置,且被static修饰时
**外部其他类可直接访问静态内部类的非静态成员
格式:new 外部类名.内部类名().内部类成员
如:new Outer.Inner().function();
**外部其他类可直接访问静态内部类的静态成员
格式:new 外部类名.内部类名.内部类成员
如:new Outer.Inner.function();
(4)什么使用时候内部类呢?
假如有A类和B类,A类想直接访问B类的成员,B类访问A类成员的时候,
需要创建A类对象进行访问,这个时候,就可以把A类定义为B类的内部类。
(5)内部类的位置
A:成员位置
**可以被private修饰(Body,Heart)
**可以被static修饰。(它访问的外部类的成员必须是静态的)
B:局部位置
**可以直接访问外部类中的成员,因为还持有外部类的持用
也可以直接访问局部成员,但是局部成员要用final修饰。
注意:局部内部类不能用private和static修饰
(6)通过class文件我们就可以区分是否带有内部类,以及内部类的位置
Outer$Inner:成员内部类
Outer$1Inner:局部内部类
28、匿名内部类(局部内部类的简写) (重点)
(1)前提:继承一个类或者实现一个接口
(注意不要弄混匿名内部类的前提和多态的前提)
(2)格式:
new 父类名或者接口名()
{
重写父类方法或者实现接口中的方法。
也可以自定义其他方法。
};
(3)什么时候定义匿名内部类?
匿名内部类只是为了简化书写,匿名内部类有局限,通常定义匿名内部类时,该类方法不超过3个
(4)匿名内部类的好处和弊端:
好处:简化代码书写
弊端:
不能直接调用自己的特有方法
不能执行强转换动作
如果该类里面方法较多,不允许使用匿名内部类
29、模板设计模式:
在定义功能时,功能的一部分是确定的,有一部分是不确定的,而且确定的部分在使用不确定的部分,
可将不确定的部分暴露出去,由该类的子类去完成。
如:求一段程序的运行时间例子。
30、异常
(1)程序运行过程中的不正常现象就叫异常。
(2)导致程序运行不正常的现象有很多,所以,就有很多的异常对象。
而这些异常对象存在着共性的内容,所以,可以不断的进行抽取。最终形成了异常的体系结构。
异常体系的根类是:Throwable
Throwable:
|--Error:重大的问题,我们处理不了。也不需要编写代码处理。比如说内存溢出。
|--Exception:一般性的错误,是需要我们编写代码进行处理的。
|--RuntimeException:运行时异常,这个我们也不需要处理。
其实就是为了让他在运行时出问题,然后我们回来修改代码。
(3)异常的分类
异常有两种:
编译时被检测异常:
该异常在编译时,如果没有处理(没有抛也没有try),编译失败。
该异常被标识,代表这可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
(4)异常体系的特点:
异常体系中的所有类及其子类对象都具备可抛性。也就是说可以被throw和throws关键字所操作。
(5)main方法是如何处理异常的。
A:在main里面编写代码进行处理
B:交给jvm自己进行处理。采用的是jvm的默认处理方式。
其实就是相当于调用了异常对象的printStackTrace()方法。
(6)Throwable类的学习
getMessage():获取异常信息,返回字符串。
toString():获取异常类名和异常信息,返回字符串。
printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
(7)异常的处理·
A:try...catch...finally
基本格式:
try
{
可能出现异常的代码
}
catch(异常对象)
{
异常处理代码
}
finally
{
释放资源
}
变形格式:
try...catch
try...catch...catch...
try...catch...catch...finally
**多个异常同时被捕获的时候,记住一个原则:
先逮小的,再逮大的。
**finally:永远被执行,除非退出jvm。System.exit(0);
面试题2个。
***:final,finally,finalize区别。
final是最终的意思。它可以用于修饰类,成员变量,成员方法。
它修饰的类不能被继承,它修饰的变量时常量,它修饰的方法不能被重写。
finally:是异常处理里面的关键字。
它其中的代码永远被执行。特殊情况:在执行它之前jvm退出。System.exit(0);
finalize:是Object类中的一个方法。
它是于垃圾回收器调用的方式。
***:假如catch中有return语句, finally里中的代码会执行吗?
是在return前,还是在return后呢?
会,在return前执行finally里面的代码。
(8)Exception和RuntimeException的区别
A:Exception:一般性的错误,是需要我们编写代码进行处理的。
B:RuntimeException:运行时异常,这个我们也不需要处理。
其实就是为了让他在运行时出问题,然后我们回来修改代码。
在用throws抛出一个的时候,如果这个异常是属于RuntimeException的体系的时候,
我们在调用的地方可以不用处理。(RuntimeException和RuntimeException的子类)
在用throws抛出一个的时候,如果这个异常是属于Exception的体系的时候,
我们在调用的地方必须进行处理或者继续抛出。
(9)自定义异常
定义类继承Exception或者RuntimeException
1,为了让该自定义类具备可抛性。
2,让该类具备操作异常的共性方法。
class MyExcepiton extends Exception
{
MyExcepiton(){}
MyExcepiton(String message)
{
super(message);
}
}
class MyException extends RuntimeException
{
MyExcepiton(){}
MyExcepiton(String message)
{
super(message);
}
}
(10)throws和throw的区别
A:有throws的时候可以没有throw。
有throw的时候,如果throw抛的异常是Exception体系,那么必须有throws在方法上声明。
B:throws用于方法的声明上,其后跟的是异常类名,后面可以跟多个异常类,之间用逗号隔开
throw用于方法体中,其后跟的是一个异常对象名
- 黑马程序员--java技术--面向对象
- 黑马程序员 java面向对象
- “黑马程序员”-Java面向对象
- 黑马程序员--java面向对象
- 黑马程序员---面向对象【java】
- 黑马程序员-------Java面向对象
- 黑马程序员--java面向对象
- 黑马程序员-java面向对象
- 黑马程序员------JAVA面向对象
- 黑马程序员:java面向对象
- 黑马程序员-----JAVA面向对象
- 黑马程序员 java面向对象
- 黑马程序员-Java面向对象
- 黑马程序员 Java面向对象
- 黑马程序员--java面向对象
- 黑马程序员-----java面向对象
- 黑马程序员--Java面向对象
- 黑马程序员 Java 面向对象
- poj 1845 Sumdiv 数论--等比数列和(逆元或者递归)
- 阿里巴巴2014笔试算法题汇总
- 《简明python教程 》总结(一)--简介(特点、安装、使用)
- python 知识点积累
- 黑马程序员--java技术--基础部分
- 黑马程序员--java技术--面向对象
- contentprovider的学习实例总结
- poj 1632 Vase collection
- 创新工场2014笔试算法题汇总
- Option Menu
- 黑马程序员--java技术--多线程
- Java之异常与错误的区别及java的异常体系
- GCD&LCM--AOJ0005
- POJ 2349 (Prim算法模板)