java李兴华学习笔记之面向对象基础资料下载.pdf
《java李兴华学习笔记之面向对象基础资料下载.pdf》由会员分享,可在线阅读,更多相关《java李兴华学习笔记之面向对象基础资料下载.pdf(27页珍藏版)》请在冰点文库上搜索。
publicstatic返回值类型方法名称(参数列表)重载:
方法名称相同,但是参数的类型或个数不同只要是定义方法,则命名规范是:
第一个单词的首字母小写,之后每个单词的首字母大写,例如:
printInfo()5、数组:
数组属于引用数据类型,所以一定要划分出内存:
栈和堆两块内存数组的定义格式:
|-格式一:
数据类型数组名称=new数据类型长度;
|-格式二:
|-声明数组:
数据类型数组名称=null;
在栈内存中开辟|-开辟数组:
数组名称=new数据类型长度;
在堆内存中开辟指定大小的数组数组的静态初始化:
数据类型数组名称=值;
取得数组长度:
数组名称.length数组可以使用方法接收,实际上这一点与内存的关系传递是一样的。
数组操作相关的方法:
java.util.Arrays.sort(数组名称)、System.arraycopy()数组拷贝2.2、本次预计讲解的知识点、本次预计讲解的知识点1、面向对象的基本概念2、类与对象的关系、引用传递3、类封装性的操作4、构造方法的定义及使用5、String类的使用6、this关键字的作用3、具体内容、具体内容3.1、面向对象的概念(了解)、面向对象的概念(了解)面向对象算是一种比较新的软件设计的方法,在没有面向对象之前使用的是面向过程(是针对于一个问题解决问题,如果修改的话,则整个设计都要修改),面向对象是针对于一类问题来进行解决,某一局部的修改不影响其他位置的变化。
在面向对象中主要分为以下三个方面:
OOA:
面向对象分析。
OOD:
面向对象设计,根据分析的结果使用工具完成设计。
北京北京MLDN软件实训中心软件实训中心联系电话:
010-51283346第(3)页共(27)页E-Mail:
OOP:
完成具体的功能实现,代码编写。
在面向对象中,实际上还存在着三个主要的特性:
封装性:
保证对外部不可见。
继承性:
继续发扬广大;
多态性:
就属于变来变去;
3.2、类与对象(、类与对象(重点重点)在整个的面向对象之中,实际上最重要的就是类与对象的关系,也就是说面向对象完全是围绕类展开的。
3.2.1、类与对象的关系、类与对象的关系既然类和对象是核心的基础部分,那么两者之间存在着怎样的关系呢?
类:
类是一组共性的产物,是同一类事物的集中表现。
对象:
是一种个性的体现,是个体的产物。
对象中的所有操作行为都由类决定,所以,在使用中只要是类定义出的操作对象都可以应用,而如果类没有定义出的操作,对象肯定无法使用。
类是对象的模板,对象是类的实例类是对象的模板,对象是类的实例3.2.2、类与对象的使用、类与对象的使用在Java中可以使用class关键字来定义一个类,在类中有两大组成部分:
属性(变量)、方法。
classPerson/定义类Stringname;
/表示一个人的姓名intage;
/表示一个人的年龄publicvoidtell()/表示一个功能,说话System.out.println(姓名:
+name+,年龄:
+age);
在本程序中就定义出了一个类,里面有两个属性:
name、age,和一个方法:
tell()。
在tell()方法将进行内容的输出。
一个类定义完成之后肯定无法直接使用,需要依靠对象进行操作,那么下面给出对象定义格式:
类名称对象名称=new类名称();
一旦有了对象之后就可以通过“对象.属性”或者是“对象.方法()”进行类的调用:
publicclassOODemo01北京北京MLDN软件实训中心软件实训中心联系电话:
010-51283346第(4)页共(27)页E-Mail:
publicstaticvoidmain(Stringargs)Personper=newPerson();
/产生对象per.name=张三;
/设置name属性的内容per.age=30;
/设置age属性的内容per.tell();
/调用方法输出;
那么下面来进一步分析以上代码的每一步操作:
对象产生:
Personper=newPerson();
既然存在了关键字new,而且类又属于引用数据类型,那么肯定现在就开辟了相应的栈及堆内存空间,而且以上的代码可以拆分成两步:
|-声明对象:
Personper=null;
在栈内存中声明|-实例化对象:
per=newPerson();
开辟对应的堆内存空间而且一定要记住的是,如果一个对象没有被实例化而直接使用的话,将出现以下的问题:
Exceptioninthreadmainjava.lang.NullPointerException表示空指向异常,因为没有对应的堆内存空间,而且此种异常肯定会经常出现,那么以上的代码实际上可以表示成以下的内存关系。
当通过“对象.属性”实际上表示的就是每一个对应的堆内存空间的属性的操作。
那么,如果现在按照以上的规律产生第二个对象肯定是不会互相影响的,因为只要存在了关键字new就表示永远会开辟新的内存空间。
/表示一个人的姓名北京北京MLDN软件实训中心软件实训中心联系电话:
010-51283346第(5)页共(27)页E-Mail:
intage;
publicclassOODemo03publicstaticvoidmain(Stringargs)Personper1=null;
Personper2=null;
per1=newPerson();
/实例化per2=newPerson();
/实例化per1.name=张三;
per1.age=30;
per2.name=李四;
per2.age=20;
per1.tell();
per2.tell();
将以上的代码再次形成内存关系图:
每一个对象拥有各自的内存空间,所以不会互相影响,而且可以发现一点,每一个对象中实际上保存的只是属性,北京北京MLDN软件实训中心软件实训中心联系电话:
010-51283346第(6)页共(27)页E-Mail:
并没有保存方法,因为所有的方法都是每个对象所共同拥有的,保存在全局代码区之中。
栈内存保存的是对堆内存的引用地址,而堆内存中保存的是每一个对象所拥有的属性,而全局代码区之中保存的是所有类中的方法,表示公共调用。
3.2.3、对象的引用传递、对象的引用传递在数组中本身也属于引用传递,而且发现所谓的引用传递指的就是一个堆内存空间,可以同时被多个栈内存所指向,那么类本身也是一样的,即:
一块堆内存可以同时被多个对象所同时指向。
publicclassOODemo04publicstaticvoidmain(Stringargs)Personper1=null;
/实例化per2=per1;
/引用传递per1.name=张三;
此就称为对象的引用传递,可以发现就是使用内存表示出关系。
但是,在使用引用传递的过程中也会存在一种问题,如下代码:
010-51283346第(7)页共(27)页E-Mail:
publicclassOODemo05publicstaticvoidmain(Stringargs)Personper1=null;
per2=per1;
现在的某些空间已经不再使用了,所以就成为了垃圾,只要是垃圾就要等待系统进行垃圾收集,在java中使用GC完成垃圾收集的操作,由于垃圾在程序中会占用系统的资源,所以在开发中一定要尽量避免过多的垃圾产生。
3.3、封装性(、封装性(重点重点)封装性属于面向对象的第一大特性,所谓的封装性就是指类内部的定义对外部不可见。
范例:
观察以下程序的问题北京北京MLDN软件实训中心软件实训中心联系电话:
010-51283346第(8)页共(27)页E-Mail:
classPerson/定义类Stringname;
publicclassEncDemo01publicstaticvoidmain(Stringargs)Personper=newPerson();
per.name=张三;
per.age=-30;
per.tell();
此时,将年龄设置成-30岁发现没有任何的错误,因为在整型的表示范围之中,是允许设置成负数的,那么在这种情况下,语法没有错,但是从实际来看肯定是错误的,因为没有任何一个人的年龄是-30岁。
那么,会造成这种问题主要就是因为现在类中的属性可以被外部直接访问,那么如果希望属性或方法不希望被外部如果希望属性或方法不希望被外部所访问的话,则可以使用所访问的话,则可以使用private关键字声明关键字声明。
classPerson/定义类privateStringname;
/表示一个人的姓名表示一个人的姓名privateintage;
/表示一个人的年龄表示一个人的年龄publicvoidtell()/表示一个功能,说话System.out.println(姓名:
per.name=张三张三;
以上在属性的声明中加入了private关键字,所以此时,程序编译的时候:
EncDemo01.java:
11:
namehasprivateaccessinPersonper.name=张三;
12:
agehasprivateaccessinPersonper.age=-30;
2errors提示的错误是name和age两个属性在Person中属于私有的访问,所以外部无法直接调用。
但是,一旦属性被封装之后,访问就成为了一个问题,所以在JAVA开发的标准规定中,只要是属性封装,则设置和北京北京MLDN软件实训中心软件实训中心联系电话:
010-51283346第(9)页共(27)页E-Mail:
取得就要依靠setter及getter方法完成操作。
例如:
现在有一个Stringname的属性setter:
publicvoidsetName(Stringn)设置的时候可以进行检查getter:
publicStringgetName()取得时候只是简单的返回classPerson/定义类privateStringname;
/表示一个人的姓名privateintage;
/表示一个人的年龄publicvoidsetName(Stringn)/设置姓名name=n;
publicvoidsetAge(inta)/设置年龄if(a=0&
a=0&
a+(str1=str2);
/falseSystem.out.println(str1=str3-+(str1=str3);
/falseSystem.out.println(str2=str3-+(str2=str3);
/false;
以上的内容确实相等,但是使用了“=”之后发现有的相等,有的不等,为什么呢?
观察内存关系决定。
010-51283346第(17)页共(27)页E-Mail:
从以上的图形中可以清晰的发现,str1和str2、str3的地址完全不一样,但是str2和str3的地址是一样的,如果按照=比较的结果来看,实际上在使用=操作的时候比较的是两个对象的内存地址,与内容无关。
所以所以“=”用用在数值上在数值上表示表示判断判断是是否相等否相等,如果是用,如果是用在了在了对象对象上上,则表示的是,则表示的是判断两判断两个对象的个对象的地址地址是是否相等。
否相等。
但是,如果现在要是想进行内容比较的话,则就只能靠String类提供的方法完成了。
No.方法名称方法名称类型类型描述描述1publicbooleanequals(StringanObject)普通判断两个字符串的内容是否相等范例:
验证equals()方法publicclassStringDemo05publicstaticvoidmain(Stringargs)Stringstr1=hello;
Stringstr2=newString(hello);
Stringstr3=str2;
System.out.println(str1equalsstr2-+(str1.equals(str2);
/trueSystem.out.println(str1equalsstr3-+(str1.equals(str3);
/trueSystem.out.println(str2equalsstr3-+(str2.equals(str3);
/true;
通过比较可以发现,虽然现在各个对象的地址不一样,但是通过了equals()方法进行比较之后,发现比较的是内容,所以,以后只要是字符串的比较操作就统一都使用equals()方法完成。
两种比较两种比较的的区别区别:
=和和equals()=:
用于数值比较,比较的是两个字符串的地址值equals():
用于内容的比较,比较两个字符串的内容是否相等3.7.3、一个字符串就是一个、一个字符串就是一个String的匿名对象的匿名对象在程序中使用“”括起来的内容就属于字符串,那么对于一个普通的字符串来讲,一个字符串就是String类的匿名对象可以直接使用。
publicclassStringDemo06publicstaticvoidmain(Stringargs)System.out.println(hello.equals(hello);
通过本程序可以清楚的进行验证,所以之前使用直接赋值的方式为String类进行实例化的操作,就属于将一个匿名对象起了一个名字。
010-51283346第(18)页共(27)页E-Mail:
3.7.4、两种实例化的区别、两种实例化的区别String类的对象可以有两种实例化方式,那么这两种到底有什么区别,以及在开发中到底该使用那种呢?
第一种Stringstr=Hello;
按照之前的理解,现在肯定是将一个字符串的堆空间的地址给str,所以图形如下:
此时的代码中,只在堆内存中开辟了一块空间,但是如果现在是第二种方式:
Stringstr=newString(Hello);
使用构造方法进行对象实例化的时候,由于内部的字符串属于匿名对象的原因,所以将产生两块堆内存空间,其中有一块将成为垃圾。
除了内存空间的少之外,如果使用了直接赋值现在还有另外一种好处,就是如果以后如果再声明了与之一样的字符串的话,则不会再重新开辟新的内存空间。
publicclassStringDemo07publicstaticvoidmain(Stringargs)Stringstr1=hello;
Stringstr2=hello;
Stringstr3=hello;
System.out.println(str1=str2-+(str1=str2);
/trueSystem.out.println(str1=str3-+(str1=str3);
/trueSystem.out.println(str2=str3-+(str2=str3);
此时返回的结果都是true,所以很明显,以上的三个String的对象都同时指向同一个堆内存空间的“hello”字符串,那么如果使用的是构造方法赋值的话,根本不可能实现此效果。
之所以内容会相等,是因为在JAVA底层中存在了一个字符串的对象池,每次的内容都会从池中取出,如果内容已经存在了,则使用已经存在的,如果不存在,则会生成一个新的,放入池中,属于共享共享设设计计模模式式。
由于这种原因,只要是使用String类的话,永远都要采用直接赋值的方式完成。
010-51283346第(19)页共(27)页E-Mail:
3.7.5、字符串的内容一旦声明则不可改变、字符串的内容一旦声明则不可改变一个字符串肯定是保存在堆内存之中的,所以一旦一个字符串声明之后,则无法改变。
publicclassStringDemo08publicstaticvoidmain(Stringargs)Stringstr=hello;
str=str+world;
str+=!
;
System.out.println(str);
现在str的内容确实改变了,但是字符串呢?
通过程序分析一下。
通过内存图可以发现一点,每一个字符串的内容原本并没有发生任何的改变,改变的是只一个字符串的内存地址的指向,而且操作完成之后会发现有很多的垃圾产生,所以,以后对于频繁修改字符串的代码应该尽可能的回避,所以以下的代码是极其垃圾的:
publicclassStringDemo09publicstaticvoidmain(Stringargs)Stringstr=hello;
for(intx=0;
x10000;
x+)str+=x;
010-51283346第(20)页共(27)页E-Mail:
System.out.println(str);
此种操作的的代码要不断的修改String的指向1000次,所以肯定将产生极大的垃圾空间,那么这种代码必须回避。
3.8、String类的相关操作(类的相关操作(重点重点)在实际的开发中,String类的使用是最频繁的,而且在String类中提供了大量的操作方法,这些操作方法对于程序的开发都是非常有帮助的,所以必须把该背的都背下来。
所有的方法都是在JDK的doc文档之中存在的。
3.8.1、字符串与字符数组、字符串与字符数组在许多的编程语言中实际上都是一直在强调一个字符串就是一个字符数组,所以在Java的String类为了体现此概念也提供了以下的一些操作方法:
No.方法名称方法名称类型类型描述描述1publicString(charvalue)构造将一个字符数组全部变为字符串2publicString(charvalue,intoffset,intcount)构造将一个字符数组的指定范围的内容变为字符串3publicchartoCharArray()普通将字符串变为字符数组4publiccharcharAt(intindex)普通返回指定位置的字符范例:
观察字符串和字符数组的转换publicclassStringAPIDemo01publicstaticvoidmain(Stringargs)Stringstr=helloworld;
charc=str.toCharArray();
/将字符串变为字符数组for(intx=0;
xc.length;
x+)System.out.print(cx+、);
System.out.println(n+newString(c);
System.out.println(newString(c,0,5);
取出指定位置的字符publicclassStringAPIDemo02publicstaticvoidmain(Stringargs)Stringstr=helloworld;
System.out.println(str.charAt(0);
System.out.println(str.charAt(3);
字符串和字符数组的关系就非常的明确了,当然也可以通过循环的方式,利用charAt()取出每一个字符的内容,如果要想循环,则肯定要确定字符串的长度,长度通过以下方法求得:
010-51283346第(21)页共(27)页E-Mail:
No.方法名称方法名称类型类型描述描述1publicintlength()普通求出字符串的长度但是一定要注意的是,在数组的操作中,可以通过“数组名称.length”求得长度。
publicclassStringAPIDemo03p