3面向对象的基本思想.docx
- 文档编号:9651778
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:32
- 大小:220.64KB
3面向对象的基本思想.docx
《3面向对象的基本思想.docx》由会员分享,可在线阅读,更多相关《3面向对象的基本思想.docx(32页珍藏版)》请在冰豆网上搜索。
3面向对象的基本思想
1.面向对象是相对于面向过程而言的,面向过程是一种谓语与宾语的关系,面向对象的是主语与谓语的关系。
面向对象三大特征:
封装:
对外部不可见,可以保护程序中的某些内容;
继承:
扩展功能
多态:
方法的重载,对象的多态性
类与对象的关系(最重要):
类是对某一类事物的描述,是抽象的、概念上的定义--名词概念;对象是实际存在的该类事物的每一个个体,因而也称为实例(instance)
2.类是对某一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每一个个体,因而也称为实例(instance)。
面向对象程序设计的重点是类的设计,而不是对象的设计。
类是通过class创建的,一个类创建后不能直接使用,需要产生对象;对象产生的格式有两种:
A.类名对象名称=null;//申明对象
对象名称=new类名();//实例化对象
B.类名对象名称=new类名();
类图:
在程序的开发中都是以类图的形式进行说明的,对于一个类来说,形式如下:
分为三个层次:
第一个层次:
表示类名,类的名称要求首字母大写
第二个层次:
表述属性的定义,按照"访问权限属性名称:
属性类型"的格式定义;
第三个层次:
表示类中的方法的定义,按照"访问权限方法名称():
方法返回值"的格式定义。
对象的进一步研究
Personper=newPerson();
A.申明对象:
Personper,栈内存中申明的,与数组一样,数组名称就是保存在栈内存中,只开辟了栈内存的对象是无法使用的,必须有其堆内存的引用才可以使用;
B.实例化对象:
newPerson(),在堆内存中开辟空间,所有的内容都是默认值;
--String是一个字符串,本身是一个类,就是一个引用数据类型,则此时默认值就是null;
--int是一个数字,本身是一个数,所以是基本数据类型,则此时的默认值是0;
如果进一步划分以上代码,可以表示如下:
Personper=null;//申明对象
Per=newPerson()//实例化对象
开发中,数据最好赋一个初值,了解了其分配的关系,就可以为属性赋值,并调用类中的方法。
使用格式:
调用属性:
对象.属性;
调用方法:
对象.方法();
如下:
publicclassTest{
publicstaticvoidmain(String[]args){
Personper=newPerson();
per.name="zhangsan";
per.age=20;
per.call();
}
}
classPerson{
Stringname;
intage;
publicvoidcall(){
System.out.println("thenameis:
"+name+",ageis"+age);
}
}
一些问题:
a.对象是保存在栈内存中,属性是保存在堆内存中,那么方法保存在哪里的呢?
方法是保存在全局代码区之中的,此区中的内容是所有对象共享的。
b.在使用对象的时候,对象必须被实例化之后才可以使用(实例化对象,并不是单单指通过new关键字实现的,只要其有堆内存的空间指向,则表示实例化成功)
c.如果不实例化会出现:
java.lang.NullPointerException(空间指向异常)的错误,这是在以后程序开发中会经常遇到的问题,应注意。
通常是在引用操作中,如果一个对象没有堆内存的引用,而调用了类中的属性和方法,就会出现这种问题。
d.可以产生多个对象,只要按照一定的格式即可。
类的引用数据类型
所谓的引用数据类型,实际上传递的就是堆内存的使用权,可以同时为一个堆内存空间定义多个栈内存的引用操作。
如:
per1=per2;
垃圾产生的原理:
publicclassTest{
publicstaticvoidmain(String[]args){
Personper1=newPerson();
Personper2=newPerson();
per1.name="zhangsan";
per1.age=20;
per2.name="xzl";
per2.age=34;
per2=per1;//在这个过程中,per2放弃了堆内存,指向了per1的堆内存,所以此时per2的堆内存就是垃圾了
System.out.print("per1中的内容---->");
per1.call();
System.out.print("per2中的内容---->");
per2.call();
}
}
classPerson{
Stringname;
intage;
publicvoidcall(){
System.out.println("thenameis:
"+name+",ageis"+age);
}
}
对象的比较:
“==”与equals();方法的区别
“==”比较两个变量的值是否相等;equals是比较两个对象的内容是否相等。
==实例1:
publicclassForTest{
publicstaticvoidmain(Stringargs[]){
Strings1=newString("abcd");
Strings2=newString("abcd");
Strings3=s1;
if(s1==s2){//s1==s3
System.out.println("true");
}else
System.out.println("false");
}
}
输出的结果是:
false
实例2:
Equals()方法代码如下:
publicclassForTest{
publicstaticvoidmain(Stringargs[]){
Strings1=newString("abcd");
Strings2=newString("abcd");
Strings3=s1;
if(s1.equals(s2)){//s1==s3
System.out.println("true");
}else
System.out.println("false");
}
}
输出的结果是:
true
封装性
A.目的:
为了是为了保护某些属性和方法,不被外部看见,保护程序
B.实现封装:
-为属性封装:
private属性类型属性名称;
-为方法封装:
private方法返回值方法名称(参数列表){}
private、public、protected;通常情况下将类的成员变量申明为private,在通过public的方法对这个变量进行访问。
对一个变量的操作,一般都有读取和赋值操作,我们分别定义两个方法来实现这两种操作,一个是getXxx(),用来读取这个成员变量的操作,一个是setXxx(),用来对这个成员变量赋值。
访问封装的内容
被封装的属性如果需要被访问,则需要编写setter及getter方法完成,并且类的属性必须都是封装的,这是必须遵守的
例如:
有一个属性privateStringname;
Setter(设置):
publicvoidsetName(Stringn){}
Getter(取得):
publicStringgetName();
如下面的代码:
publicclassTest{
publicstaticvoidmain(String[]args){
Personper1=newPerson();
per1.setName("zhangsan");
per1.setAge(-10);//此时存在一个情况,不符合现实中的需求
per1.call();
}
}
classPerson{
Stringname;
intage;
publicvoidsetName(Stringa){//set方法
name=a;
}
publicvoidsetAge(intb){
age=b;
}
publicStringgetName(){
returnname;
}
publicintgetAge(){
returnage;
}
publicvoidcall(){
System.out.println("thenameis:
"+name+",ageis"+age);
}
}
上面的代码中只是可以访问封装的内容,但是对属性的赋值还没有验证,需要在set方法中加入验证,注意:
一定是在set方法中进行验证。
如下:
if(b>=0&&b<=150){
age=b;
}
elseage=0;
此时就达到了实际中的要求了。
封装的类图表示
减号表示用private封装了。
构造函数。
只要一有对象实例化则就会调用构造方法。
类名对象=new类名();//调用的就是一个构造方法;
构造方法的特征
-它具有与类相同的名称
-构造方法的申明处不能有任何返回值类型的申明
-它不能在方法中用return语句返回一个值;
注意:
不同于void,如果加上void,则不会自动调用;
构造方法的作用和调用时机:
在申明对象时不会调用,当一个类的实例对象刚产生时,这个类的构造方法就会被自动调用,主要作用是为类中的属性进行初始化。
如下面的代码:
实例3:
publicclassTest{
publicTest(){//如果不写,编译器会自动创建
System.out.println("hello!
boy");
}
publicstaticvoidmain(String[]args){
Testt1=newTest();
}
}
构造方法的重载
和一般的方法重载一样,重载的构造方法具有不同个数或不同类型的参数,编译器就可以根据这一点判断出用new关键字产生对象时,该调用哪一个构造方法,产生对象的格式是:
new类名(参数列表);如下面的例子:
实例4:
publicclassTest{
intage;
Stringname;
//不带参数的构造方法
publicTest(){
}
//带一个参数的重载构造方法
publicTest(Stringx){
x=name;
}
//带两个参数的构造方法
publicTest(Stringx,inty){
name=x;
age=y;
}
//对测试的数据进行输出的函数
publicvoidtest(){
System.out.println(name+"'sageis"+age);
}
publicstaticvoidmain(String[]args){
Testt1=newTest();//如果上面不要不带参数的构造方法,编译器会报错,//因为这时编译器不会自动产生不带参数的构造方法,因为下面已经重载了构造方法
Testt2=newTest("xzl");
Testt3=newTest("xzl",22);
t1.test();
t2.test();
t3.test();
}
}
匿名对象
在Java中,如果一个对象只使用一次,则就可以将其定义为匿名对象;如:
newPerson().call();所谓的匿名对象就是比之前的对象少了一个栈内存的引用关系;
3.this关键字的使用,举例如下:
publicclassTest{
intage;
Stringname;
//不带参数的构造方法
publicTest(){
}
//带一个参数的重载构造方法
publicTest(Stringname){
this.name=name;//加上this后,可以增加代码的可读性
}
//带两个参数的构造方法
publicTest(Stringname,intage){
this.name=name;
this.age=age;
}
//对测试的数据进行输出的函数
publicvoidtest(){
System.out.println(name+"'sageis"+age);
}
publicstaticvoidmain(String[]args){
Testt1=newTest();//如果上面不要不带参数的构造方法,编译器会报错,因为这时编译器不会自动产生不带参数的构造方法,因为下面已经重载了构造方法
Testt2=newTest("xzl");
Testt3=newTest("xzl",22);
t1.test();
t2.test();
t3.test();
}
}
4.Java中垃圾回收分析:
Finalize()是在对象变为垃圾,在被清除内存前调用的,System.gc是直接调用垃圾回收器,清楚垃圾。
可以用finalize()方法和System.gc结合的方式看到Java垃圾回收的效果。
实例:
publicclassTest{
publicvoidfinalize(){
System.out.println("thegubishiscomming!
");
}
publicstaticvoidmain(String[]args){
newTest();
newTest();
newTest();
System.gc();
}
}
静态代码块:
代码块实际上是指用{}括起来的一段代码,根据位置的不同,代码块可以分为四种:
普通代码块、构造块、静态代码块、同步代码块,其中同步代码块将在多线程部分讲解。
普通代码块
直接定义在方法中的代码块称为普通代码块。
publicclassTest{
publicstaticvoidmain(String[]args){
{
inta=20;//静态代码块,定义在方法中
System.out.println("普通静态代码块--->"+a);
}
inta=100;//局部变量
System.out.println("代码块之外--->"+a);//普通变量输出
}
}
构造块
把代码块定义在类中,则成为构造类
publicclassTest{
publicstaticvoidmain(String[]args){
newDemo();
newDemo();
newDemo();
}
}
classDemo{
{//直接在类中编写的代码块,称为构造块
System.out.println("1、构造块");
}
publicDemo(){//定义构造方法
System.out.println("2、构造方法");
}
}
构造块优先于构造方法执行,且执行多次。
只要一有实例化对象产生,就执行构造块中的内容
静态代码块
直接使用static关键字申明的代码块就称为静态代码块
publicclassTest{
publicstaticvoidmain(String[]args){
newDemo();
newDemo();
newDemo();
}
static{
System.out.println("在主方法所在类中定义的静态代码块");//在主方法所在的类中定义的静态代码块
}
}
classDemo{
{//直接在类中编写的代码块,称为构造块
System.out.println("1、构造块");
}
static{
System.out.println("0、静态代码块");//static代码块
}
publicDemo(){//定义构造方法
System.out.println("2、构造方法");
}
}
静态块优先于主方法执行,如果在普通类中定义的静态块,优先于构造块执行,不管有多少个实例化对象产生,静态代码块只执行一次,静态代码块的主要功能就是为静态属性初始化。
实例:
不用main方法,在屏幕上输出“helloworld”
publicclassTest{
static{
System.out.println("helloworld!
");//运用的在主方法所在类中定义的静态代码块优于主方法执行
}
}
虽然可以打印出结果,但是也会出现Exceptioninthread"main"java.lang.NoSuchMethodError:
main这样的提示,为了不让它出现这样的提示,可以在代码中加入程序退出的代码:
publicclassTest{
static{
System.out.println("helloworld!
");//运用的在主方法所在类中定义的静态代码块优于主方法执行
System.exit
(1);//程序退出
}
}
Java单态模式和构造方法私有化
构造方法私有化
类的封装性不光体现在对属性的封装上,实际上方法也是可以被封装的,当然,在方法封装中也包含了对构造方法的封装。
例如以下的代码,就是对构造方法进行了封装:
classSingleton{
privateSingleton(){//将此构造方法进行封装
}
publicvoidprint(){
System.out.println("HelloWorld!
");
}
}
如果现在在外部要进行实例化,在编译的时候就会出现错误:
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Singletons1=null;//申明对象
s1=newSingleton();//实例化对象,此时会出现错误,因为构造方法是私有的
}
}
classSingleton{
privateSingleton(){//将此构造方法进行封装
}
publicvoidprint(){
System.out.println("HelloWorld!
");
}
}
既然是外部不能实例化,那么在内部呢?
classSingleton{
Singletoninstance=newSingleton();
privateSingleton(){//将此构造方法进行封装
}
publicvoidprint(){
System.out.println("HelloWorld!
");
}
}
一个类的构造方法被私有化之后,则只能从其类的内部取得实例化对象,那么此时要考虑的问题就是如何把内部生成的instance对象拿到外部类,这样外部就可以直接通过此对象进行实例化。
正常情况下,instance属性只能通过Singleton类的实例化对象才可以进行调用,如果在没有实例化的时候依然可以取得instance对象,则需要将instance申明为static访问类型。
因为使用static申明的变量,可以直接使用类名称进行访问。
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Singletons1=null;//申明对象
s1=Singleton.instance;//实例化对象,类名.属性
s1.print();
}
}
classSingleton{
privatestaticSingletoninstance=newSingleton();
privateSingleton(){//将此构造方法进行封装
}
publicvoidprint(){
System.out.println("HelloWorld!
");
}
}
正常情况下这些属性应该进行封装,所以对以上的代码进行修改:
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Singletons1=null;//申明对象
s1=Singleton.getInstance();//实例化对象,此时会出现错误
s1.print();
}
}
classSingleton{
privatestaticSingletoninstance=newSingleton();
privateSingleton(){}//将此构造方法进行封装
publicstaticSingletongetInstance(){
returninstance;
}
publicvoidprint(){
System.out.println("HelloWorld!
");
}
}
为什么要对构造方法私有化呢?
为什么不直接通过实例化的形式产生对象?
如下面的一段代码:
同时产生本类的三个对象
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Singletons1=null;//申明对象
Singletons2=null;//申明对象
Singletons3=null;//申明对象
s1=Singleton.getInstance();//取得实例化对象
s2=Singleton.getInstance();//取得实例化对象
s3=Singleton.getInstance();//取得实例化对象
s1.print();
s2.print();
s3.print();
}
}
classSingleton{
privatestaticSingletoninstance=newSingleton();
privateSingleton(){}//将此构造方法进行封装
publicstaticSingletongetInstance(){
returninstance;
}
publicvoidprint(){
System.out.println("HelloWo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 对象 基本 思想