Java基础_面向对象_类与对象、构造函数、关键字、静态代码块、单例
2013-09-11 09:15
253 查看
面向对象概念
相对面向过程而言,都是一种思想面向过程强调的是功能行为
面向对象将功能封装进对象,强调具备了功能的对象
从执行者到指挥者
面试时结合实际场景描述面向对象
万物皆对象:你所接触到的,所想到的概念都可以是一个对象。面试不要说
写程序时不要先考虑功能,先面对对象。先找Java中是不是已经提供好了相对应的对象。没有对象,自己造一个对象,把功能定义到里面去
名词提炼法:把名词提炼出来封装成对象
面向对象三个特征:封装,继承,多态
以后开发:其实就是找对象使用,没有对象,就创建对象。
找对象,建立对象,使用对象。维护对象的关系
类与对象的关系
类:就是对像是生活中事物的描述对象:就是这类事物实实在在存在的个体
类的描述:提取对象中共性内容,对具体的抽象
映射到java中,描述就是class定义的类。
具体对象就是对应java在堆内存中用new建立的实体,实体的成员变量都有默认初始化值。
定义类其实就是在描述事物的属性和行为,属性对应类中的变量,行为对应类中的函数(方法)
属性和行为共同称为类中的成员。属性称为成员变量,行为称为成员函数
Car c = new Car();//c就是一个类类型变量(引用星变量的一种)。记住:类类型变量指向对象
在java中指挥对象方式:对象.对象成员
对象的特点在于封装数据
成员变量和局部变量
作用范围:
成员变量作用于整个类中局部变量作用于函数中,或者语句中
在内存中的位置:
成员变量在堆内存中,因为对象的存在才在内存中存在局部变量存在于栈内存中,使用完就消失
匿名对象
是对象的简化形式,没有名字new Car().run();
两种使用情况
1、当对对象方法仅进行一次调用的时候(因为调用方法匿名对象有意义,调用属性没有意义)。如果对多个成员调用,就必须给该对象取一个名字
2、匿名对象可以作为实际参数进行传递:show(new Car());写缓存的时候就会考虑到强引用,弱引用,软引用,定义对象的生命周期
封装
面向对象特性之一,是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。透明的<==>隐藏的
好处:
将变化隔离便于使用
提高重用性
提高安全性
封装原则:
将不需要对外提供的内容都隐藏起来把属性都隐藏,提供公共方法
函数、类、包、框架都是封装体
private:
私有,权限修饰符中的一种,用于修饰类中的成员(成员变量、成员函数)。私有只在本类中有效
将成员变量私有化以后,需要在类中提供访问该成员变量的方法(setAge()和getAge())
之所以对外提供访问方式,是因为可以在访问方法中加入逻辑判断语句,对访问的数据进行操作,提高代码的健壮性
私有仅仅是封装的一种表现形式
构造函数
特点:
1、函数名与类名相同2、不用定义返回值类型,与void不同,注意区别
3、不可以写return语句
作用:
给对象进行初始化注意:
1、默认构造函数的特点2、多个构造函数是以重载的形式存在的
对象一建立,就会调用与之对应的构造函数
当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数:Person(){}
当在类中自定义了构造函数后,默认的构造函数就没有了
构造函数和一般函数的不同:
在写法上不同在运行上不同。构造函数是在对象已建立就运行,给对象初始化
而一般方法是对象调用才执行,是给对象添加对象具备的功能
一个对象建立,构造函数只运行一次,而一般方法可以被对象调用多次
什么时候定义构造函数?
当分析事物时,该事物一存在就具备一些特性或者行为,那么将这些内容定义在构造函数中。面试:构造代码块
作用:给对象进行初始化对向一建立,就运行,而且优先于构造函数执行(先运行,不论构造代码块在构造函数前面还是后面)
和构造函数的区别:
构造代码块是给所有对象进行统一初始化,定义不同对象共性初始化内容。而构造函数是给对应的对象初始化
class Person
{
{//构造代码块
Sop("");
}
Person()//构造函数
{
...
}
}
构造函数可以私有化private
那么不能用该构造函数创建对象(单例设计模式)this关键字
构造函数中局部变量的名称和成员变量的名称相同,用this标识成员变量,看上去是用于区分局部变量和成员变量重名的情况this代表本类的对象,代表它所在函数所属对象的引用,简单说哪个对象在调用this所在的函数,this就代表那个对象
在类中被对象调用的成员,包括变量和函数
变量出现同名情况一定要加
类里面的成员被使用全是由对象完成的,而本类中的对象是this
this的应用
当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部用到了本类对象都用this代表构造函数间调用
this语句:用于构造函数之间互相调用,只能定义在构造函数的第一行,因为初始化中的初始化要先执行,再执行自己的初始化,保证输出符合用户的输入。
Person(String name, int age)
{
this(name);//注意没有点,this代表对象
this.age = age;
}
不允许存在死循环的调用,示例如下:
Person()
{
this("haha");
}
Person(String name)
{
this();
}
static关键字
原因:
多个对象当中存在着共同数据,没有必要每一个对象都具备一个从而浪费内存空间是一个修饰符,用于修饰成员(成员变量和成员函数)。不在堆内存当中,在方法区/共享区/数据区中
被修饰后的成员具备以下特点:
1、随着类的加载而加载,随着类的消失而消失,说明它的生命周期最长,非静态成员/实例变量则不是String name;//成员/实例变量
static String country = "cn";//静态成员变量/类变量
2、优先于对象存在。
3、被所有对象所共享
4、除了可以被对象调用外,还可以直接被类名调用(类名.静态成员)
实例变量和类变量的区别:
1、存放位置。类变量随着类的加载而存在于方法区中
实例变量随着对象的简历存在于对内存中
2、生命周期
类变量生命周期最长,随着类的消失而消失
实例变量生命周期随着对象的消失而消失
static使用注意事项:
静态方法只能访问静态成员,非静态方法既可以访问静态也可以访问非静态静态方法中不可以写this,super关键字。因为静态优先于对象存在。
主函数是静态的
静态有利有弊
利:对对象的共享数据进行单独空间的存储,节省空间。
可以直接被类名调用。
弊:
生命周期过长。
访问出现局限性。(静态虽好,只能访问静态)
主函数main
主函数是一个特殊的函数,作为程序的入口,可以被jvm调用主函数的定义:
public:代表着该函数的访问权限最大
static:代表主函数随着类的加载就已经存在了。
void:主函数没有具体的返回值
main:不是关键字,但是是一个特殊的单词,可以被jvm识别。
(String[] arr): 函数的参数,参数类型是一个字符串类型的数组
主函数是固定格式的,包括参数格式,jvm可识别。虽然main可重载,但能被jvm识别的只有一种格式。只有args可以更改
jvm在调用主函数时传入的是new String[0];
主函数传值;
class MainDemo
{
public static void main(String[] args)
Sop(args[0]);
}
命令:java MainDemo haha hehe heihei
结果:haha
什么时候使用静态?
要从两方面考虑,因为静态修饰的内容有成员变量和成员函数什么时候定义静态变量(类变量)?
当对象中出现共享数据时,该数据被静态所修饰
对象中的特有数据要定义成非静态存在于堆内存中
什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
例:
class Person
{
String name;
public static void show()
{
Sop("haha");
}
}
静态的应用--工具类
在工具类中的方法都定义成静态的,因为没有操作该类的特有数据。将方法静态后,可以方便于使用,但是该类还是可以被其他程序建立对象的。为了更为严谨,强制让该类不能建立对象,可以通过将构造函数私有化完成
当一个类中用到了其他类,编译时该类文件时jvm先找当前目录下有无其他类的class文件,如果没有,则找有无java文件进行编译,最后才编译自己的java文件
帮助文档的制作javadoc
将工具类文件(ArrayTool.class)发送给他人,其他人只要将该文件设置到classpath路径下,就可以使用该工具类了设置工具类的路径
set classpath = .;c:\myclass//加上点先找当前目录,再找指定目录将A
但是该类中到底定义了多少个方法使用者不清楚,因为该类并没有使用说明书。
java的说明书通过文档注释完成
类的描述信息
/**这是一个可以对数组进行操作的工具类,该类中提供了获取最值,排序等功能。
@author 张三
@version V1.1
*/
功能描述
凡是public修饰的功能都用文档注释描述,因为都可以被文档注释工具所提取/**
获取一个整型数组中的最大值
@param arr 接受一个int类型的数组
@return 会返回一个该数组中的最大值
*/
javadoc -d 目录
javadoc -d myhelp -author -version ArrayTool.java//myhelp表示在当前目录下创建的文件夹名称(也可以指定路径)-author -version表示提取作者和版本
要将一个类生成帮助文档,该类必须是public修饰
只有两种权限才会被体现到注释文档中:public和protected,包括构造方法(如果需要对外提供给)
一个类中默认会有一个空参数的构造函数,这个函数的权限和所属类一致,如果类被public修饰,那么默认的构造函数也带public修饰符。
空参数构造函数不是默认构造函数,默认构造函数是看不见的
静态代码块
格式:
static{
静态代码块中的执行语句;
}
特点:
随着类的加载而执行,只执行一次。优先于主函数用于给类进行初始化
StaticCode s = null;//不会加载类,但凡用到了类中的内容了,才会加载类。
注意:构造代码块给该类的所有对象初始化,静态代码块给类初始化,构造函数给对应对象初始化
对象的初始化过程
Person p = new Person("zhangsan", 20);1、因为new用到了Person.class文件,所以会先找到Person.class文件并加载到内存中
2、执行该类中的静态代码块,如果有的话,给Person.class类进行初始化
3、在堆内存中开辟空间,分配内存地址
4、在堆内存中建立对象的特有属性,并进行默认初始化
5、对属性进行显示初始化
6、对对象进行构造代码块初始化
7、对对象进行与之对应的构造函数初始化
8、将内存地址赋给栈内存中的P变量
单例设计模式
设计模式:解决某一类问题最行之有效的方法,java中有23种设计模式;单例设计模式:解决一个类在内存中只存在一个对象
想要保证对象唯一
1,为了避免其他程序过多建立该类对象,先控制禁止其他程序建立该类对象
2,还为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
代码体现:
1、将构造函数私有化
2、在类中创建一个本类对象
3、提供一个方法可以获取到该对象
饿汉式
class Single{
private Single(){}
private static final Single s = new Single();//类中的成员变量得私有化,final 使得s常量化,终身指向Single的实例
public static Single getInstance()//在外部不能通过对象访问,则只能铜鼓类名访问,所以方法是静态的
{
return s;
}
}
通过Single ss = Single.getInstance();//获取该对象
Single s1 = Single.getInstance();//main里面又多了一个变量s1,getInstance()方法还是返回的方法区中s的值,就保证了对象的唯一性
对于事物该怎么描述,还怎么描述,当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。(比如配置文件的数据封装在一个单例设计模式设计完的类当中)
上面的代码是先初始化对象。
称为饿汉式。
懒汉式
对象是方法被调用时才初始化,也叫做对象的延时加载,称为:懒汉式(有多线程问题,面试常考)class Single
{
private static Single s = null;//此处不能加final
private Single(){}
public static Single getInstance()
{
if(s==null)
s = new Single();
return s;
}
}
饿汉式和懒汉式的区别
饿汉式是Single类一加载进来,方法区里面就有s,堆里面就有对象,对象的地址值就赋给了s懒汉式是Single类一加载s是空。当调用getInstance方法的时候,这个方法运行才在内存中建立对象,并把对象的内存地址值赋给s,才称为延时加载
懒汉式的缺点
cpu在某一时刻只能处理一个程序,如果多个人同时调用getInstance方法,在if(s==null)
-->A程序停在此处
-->B程序停在此处
当A执行创建对象过后再执行B程序会创建多个对象
public static synchronized Single getInstance()//通过synchronized关键字上锁,A程序一进来其他程序就进不来了。因为每次都会判断锁,所以效率会变低,有判断。
最终解决方案
public static Single getInstance()
{
if(s==null)//此判断可以减少判断锁的次数,所以效率高
{
synchronized (Single.class)
{
if(s==null)//同步代码块加入判断的原因:如果第一个线程进入到第一个if代码块,此时并还没获取锁,此时虚拟机切换给第二个线程,它也进来了if代码块,并且此时获取锁,new一个对象,然后返回。接着虚拟机切换给第一个线程,它这时候才获取锁,此时如果没有第二个if判断,就会再new 一个对象,这就不能保证类的对象唯一性。也可以理解为在同步的外层加上if判断,来减少判断锁的次数。
s = new Single();
}
}
return s;
}
开发的时候用第一种饿汉式,安全,简单
相关文章推荐
- 黑马程序员——Java基础---面向对象(面向对象,类,对象,匿名对象,封装,构造函数,构造代码块,this,static,main,帮助文档,静态代码块,单例)
- Java基础<五>---> 面向对象与类(匿名对象、构造函数、this、静态等)
- 黑马程序员 Java基础<一>---> 面向对象与类之概述(匿名对象、封装、构造函数、this、静态等)
- 黑马程序员_Java基础_面向对象(概述、类与对象关系、成员变量、封装private、构造函数和构造代码块、this关键字)
- java--面向对象(static关键字、main、静态什么时候使用、静态代码块、对象的初始化过程)
- 【java基础】 静态 关键字 static(构造函数、构造代码块、静态代码块的区别)
- 黑马程序员——Java面向对象(一)之匿名对象、代码块、static关键字等
- java基础之----静态代码块和静态方法、以及static 关键字
- 什么是静态代码块?java中如何使用空参构造方法自动生成不同名字的对象,使用非静态的属性和静态属性有什么区别,原因是什么?如何理解static关键字
- 黑马程序员 JAVA初级-面向对象 匿名对象、封装、构造函数、构造代码块、this
- Java重修之路(七)面向对象之静态,主函数,Doc文档,静态代码块,对象初始化过程,单例设计模式
- 黑马程序员_Java基础_面向对象,封装,继承,单例设计模式,构造函数,构造代码块
- 【java基础】——java面向对象(上)—面向对象、类与对象、封装、构造函数等
- 16-面向对象(static关键字-什么时候用) 面向对象-Static难点 18-面向对象(构造代码块).(静态代码块)
- 【Java基础】----static关键字、代码块、Main方法、匿名对象详解
- 黑马程序员——Java基础语法 之面向对象(概念,特征,this,static关键字,代码块)
- Java基础--面向对象(封装、构造函数、构造代码块、this关键字)
- 黑马程序员_Java基础_面向对象(继承、子父类变量和函数以及构造函数特点、final关键字、抽象类、模版方法模式、接口)
- 三、Java基础---------关于继承、构造函数、静态代码块执行顺序示例讲解
- 5.1JAVA基础复习——JAVA中的静态代码块、构造代码块、构造函数、局部代码块区别