第二篇Java核心技术复习

1.类和对象

1.1面向对象的概念

      面向对象是一种符合人类思维习惯的编程思想。现实生活中存在各种形态不同的事物,这些事物之间存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象。
       提到面向对象,自然会想到面向过程,面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候依次调用就可以了。面向对象则是把构成问题的事务按照一定规则划分为多个独立的对象然后通过调用对象的方法来解决问题。当然,一个应用程序会包含多个对象,通过多个对象的相互配合来实现应用程序的功能,这样当应用程序功能发生变动时,只需要修改个别的对象就可以了,从而使代码更容易得到维护。面向对象的特点主要可以概括为封装性、继承性和多态性,接下来针对这三种特性进行简单介绍。

1、封装性

封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节,这就是封装思想。例如,用户使用电脑,只需要使用手指敲键盘就可以了,无需知道电脑内部是如何工作的,即使用户可能碰巧知道电脑的工作原理,但在使用时,并不完全依赖电脑工作原理这些细节。

2、继承性

继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。例如,有一个汽车的类,该类中描述了汽车的普通特性和功能,而轿车的类中不仅应该包含汽车的特性和功能,还应该增加轿车特有的功能,这时,可以让轿车类继承汽车类在轿车类中单独添加轿车特性的方法就可以了。继承不仅增强了代码的复用性、提高开发效率,还为程序的维护补充提供了便利。

3、多态性
多态性指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其它类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。例如,当听到“Cut”这个单词时,理发师的行为是剪发,演员的行为表现是停止表演,不同的对象,所表现的行为是不一样的。
面向对象的思想光靠上面的介绍是无法真正理解的,只有通过大量的实践去学
习和理解,才能将面向对象真正领悟。接下来的第三章、第四章将围绕着面向对象的三个特征(封装、继承、多态)来讲解Java这门编程语言。

3.2 类与对象

       面向对象的编程思想,力图让程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出了两个概念,即类和对象。其中,类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。接下来通过一个图例来抽象描述类与对象的关系,如下图所示。

   下图可以将玩具模型看作是一个类,将一个玩具看作对象,从玩具模型和玩具之间的关系便可以看出类与对象之间的关系。类用于描述多个对象的共同特征,它是对象的模板。对象用于描述现实中的个体,它是类的实例。从图可以明显看出对象是根据类创建的,并且一个类可以对应多个对象。

71cd5feb6c16407f97a74783220ea508.jpg

 类的定义

在面向对象的思想中最核心的就是对象,为了在程序中创建对象,首先需要定义一个类。类是对象的抽象,它用于描述一组对象的
共同特征和行为。类中可以定义成员变量和成员方法,其中成员变量用于描述对象的特征,也被称作属性,成员方法用于描述对象的行为,可简称为方法。
 代码:

4715e82d36c14c26b42f59b215eb65bf.png

      在Java中,定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量。如果在某一个方法中定义的局部变量与成员变量同名,这种情况是允许的,此时方法中通过变量名访问到的是局部变量,而并非成员变量,请阅读下面的示例代码:

class Person{

intage=10;//类中定义的变量被称作成员变量 void speak(){

intage=60;//方法内部定义的变量被称作局部变量

System.outprintin("大家好,我今年"+age+"岁!")

}}

      上面的代码中,在Person类的speak()方法中有一条打印语句,访问了变量age此时访问的是局部变量age,也就是说当有另外一个程序来调用speak()方法时,输出的值为60,而不是10。

对象的创建与使用

     应用程序想要完成具体的功能,仅有类是远远不够的,还需要根据类创建实例对象在Java程序中可以使用new关键字来创建对象,具体格式如下:

类名  对象名称=new类名();

>例如,创建Person类的实例对象代码如下:

Person p=new Person();

      上面的代码中,“newPerson()”用于创建Person类的一个实例对象,“Personp”则是声明了一个Person类型的变量p。中间的等号用于将Person对象在内存中的地址赋值给变量p,这样变量p便持有了对象的引用。

05040f50aacf40d9845565fb5dd9f759.png

 

     在实例化对象时,Java虚拟机会自动为成员变量进行初始化,针对不同类型的成员变量,Java虚拟机会赋予不同的初始值,如下表示。
成员变量类型    初始值    
byte    0e    
shorte
inte    0p    
long    0L    
fioat    0.0F    
double    0.0D-    
char    空字符,u0000    
boolean-    false    
引用数据类型    nulle    

       当对象被实例化后,在程序中可以通过对象的引用变量来访问该对象的成员。需要注意的是,当没有任何变量引用这个对象时,它将成为垃圾对象。

代码:

cdbcbda2a77f4a30bac5f1a525482e60.png

 类的设计

       在Java中,对象是通过类创建出来的。因此,在程序设计时,最重要的就是类
的设计。接下来就通过一个具体的案例来学习如何设计一个类。
       假设要在程序中描述一个学校所有学生的信息,可以先设计一个学生类
(Student),在这个类中定义两个属性name、age分别表示学生的姓名和年龄,定义一个方法introduce()表示学生做自我介绍。根据上面的描述设计出来的 Student类如下所示。

public class Student {
String name; //定义一个姓名属性+
int age:    //定义一个年龄属性    
public void introduce() {*
1/方法中打印属性name和age的值
System.out.printin("大家好,我叫” +name +”,我今年"+ age+“岁!”);

}}

代码:

e418afbb485f46d98b91ed32f1ce83f6.png

 类的封装

     在设计一个类时,应该对成员变量的访问作出一些限定,不允许外界随意访问。这就需要实现类的封装。
        所谓类的封装是指在定义一个些时,将类中的属性私有化,即使用private关键字来修饰,私有属性只能在实所在类中被访问,如果外界想要访问私有属性,需要提供一些使用public你饰的公有方法,其中包括用于获取属性值的getxxx方法和设置属性值的setXxx方法

代码:

675d6535bf3a4d979a9695d6189fb42a.png

7150f513e7dc48a4ac16c9f1098dbafa.png 

eccc2889467947299e7e2838ad84bba3.png 

1a3a4eff5dcc40408b2db5d170091bf6.png 

5df522801ada4fd489e08a8b8f4301b9.png 

c9dab946cfd3470db6633d98dfbc0b56.png 

d194d780ac004570b09905fae7d3f361.png 

6137e248f8b4499695b1ff846b219559.png 

案例代码 1e6b90bcc8e848289584ef8183d6ed4f.png

798a79c114aa442ebc1c9cc271fbbc12.png 

a3106242c82549dbb7d96b2992127979.png 

 3.3 构造方法

构造方法的定义

      在一个类中定义的方法如果同时满足以下三个条件,该方法称为构造方法,具体如下:

      方法名与类名相同

       在方法名的前面没有返回值类型的声明

        在方法中不能使用return语句返回一个值,但是可以单独写return语句来作为方法的结束。

22765c2805ba4e0d87243a8703791ea6.png

da1ba1e393084cf492d686cb00d0448c.png 

d33c081b2a184e119493d93b99dde119.png 

 

构造方法的重载

与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。在创建对象时,可以通过调用不同的构造方法来为不同的属性进行赋值。

8e3d07d943b246d29b056fce317cdcd5.png

1b3847e8c5b24908b62a716726f9b540.png 

51e21920a20d406492bfeff6cdecaa59.png 

275ff8387409469fb6c4f2526f6a8fa2.png 

afad04923d764dd8a12393cbb713c6b5.png 

 3.4 this关键字      
      例如都声明为age。但是这样做又会导致成员变量和局部变量的名称冲突,在方法中将无法访问成员变量age。为了解决这个问题Java中提供了一个关键字 this来指代当前对象,用于在方法中访问对象的其它成员。

c95b93a4a9b046e6b4b685233f638f47.png

 

3.5 垃圾回收     
       在Java中,当一个对象成为垃圾后仍会占用内存空间,时间一长,就会导致内存空间的不足。针对这种情况,Java中引入了垃圾回收机制。有了这种机制,程序员不需要过多关心垃圾对象回收的问题,Java虚拟机会自动回收垃圾对象所占用的内存空间。

        一个对象在成为垃圾后会暂时地保留在内存中,当这样的垃圾堆积到一定程度时,lava虚拟机就会启动垃圾回收器将这些垃圾对象从内存中释放,从而使程序获得更多可用的内存空间。除了等待Java虚拟机进行自动垃圾回收外,还可以通过调用
System.gc()方法来通知Java虚拟机立即进行垃圾回收。当一个对象在内存中被释放时,它的finalize()方法会被自动调用,因此可以在类中通过定义finalize()方法来观察对象何时被放。

21665b5533f14e5dbfcf8521d959f2c3.png

 3.6 static关键字 

静态变量

      在定义一个类时,只是在描述某类事物的特征和行为,并没有产生具体的数据只有通过new关键字创建该类的实例对象后,系统才会为每个对象分配空间,存储各自的数据。有时候,开发人员会希望某些特定的数据在内存中只有一份而且能够被一个类的所有实例对象所共享。例如某个学校所有学生共享同一个学校名称,此时完全不必在每个学生对象所占用的内存空间中都定义一个变量来表示学校名称,而可以在对象以外的空间定义一个表示学校名称的变量,让所有对象来共享。

83b25dc54b5442aa8a3852cfc39019f9.png

 

静态方法

       在实际开发时,开发人员有时会希望在不创建对象的情况下就可以调用某个方法,换句话说也就是使该方法不必和对象绑在一起。要实现这样的效果,只需要在类中定义的方法前加上static关键字即可,通常称这种方法为静态方法。同静态变量一样,静态方法可以使用“类名方法名”的方式来访问,也可以通过类的实例对象来访问。
       注意:在一个静态方法中只能访问用static修饰的成员,原因在于没有被static修饰的成员需要先创建对象才能访问,而静态方法在被调用时可以不创建任何对象。

3970323d0aad417a9c30f2d0fd5ca65e.png

 

静态代码块

在Java类中,使用一对大括号包围起来的若干行代码被称为一个代码块,用static关键字修饰的代码块称为静态代码块。当类被加载时,静态代码块会执行。由于类只加载一次,因此静态代码块只执行一次。在程序中,通常会使用静态代码块来对类的成员变量进行初始化。

4c485c4f4330453797ebb7da07dc3705.png

 

3.7 成员内部类
       在Java中,允许在一个类的内部定义类,这样的类称作内部类,这个内部类所在的类称作外部类。根据内部类的位置、修饰符和定义的方式可分为:成员内部类、静态内部类、方法内部类。本小节将针对成员内部类进行讲解。
       在一个类中除了可以定义成员变量、成员方法,还可以定义类,这样的类被称作成员内部类。在成员内部类中,可以访问外部类的所有成员。

        如果想通过外部类去访问内部类,则需要通过外部类对象去创建内部类对象,创建内部类对象的具体语法格式如下:

外部类名内部类名变里名=new外部类名()new内部类名();

ba8010a8ec2942798f0d3718bede03bb.png

ef700e6d0e49475b9584a5c8d5e7115e.png 

7ef8db66134545218948f958567be251.png 

24f5fac3fafa4d6da3d2f9e8af34f41c.png 

 代码案例:

af1a178a12f546f4991f05ec511ced3e.png

eca22bbc0abf47e5ad32e8d4365851ad.png 

94bbcc3861b24fb0a6bf17602d56b37b.png 

5b214fcbbd2044b8a080075cf4be5657.png 

1b2140a738ca4c7db0c9e217dae632e9.png 

 

4.1 类的继承       
继承的概念

人在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物,同理,波斯猫和巴厘猫继承自猫,而沙皮狗和斑点狗继承自狗。这些动物之间会形成一个继承体系

,具体如图:

fa8cd9955408445f8b25a7baa7769138.png

 

4bf741c887204092acdfebda023bbf06.png

6dd0914a9fa8466f8c4eaa87fd5aadee.png 

在Java中,类的继承是指在一个现有类的基上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。在程序中,如果声明一个类继承另一个类,需要使用extends关键字。 

 

 

    在类的继承中,需要注意一些问题,具体如下:
1.在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类,例如下面这种情况是不合法的。
class A{} + class B()+
class Cextends AB{}//类不可以同时继承A类和B类+
2.多个类可以继承一个父类,例如下面这种情况是允许的。

cla3s A{}+
class B extends A{)
classCextendsA)//类B和类都可以继承类A
3.在Java出,多层继用是可以的,即一个尖的又尖可以再去继承另外的父类,例
如c类继承自B类,而B类又可以去继承A类,这时,c类也可称作A类的子类。例如下面这种情况是允许的。

class Alld
class BextendaA(}//类B继承类A,类B是类的子类
4.在Jan.classcextendaB1) //类c维承类B,类c是类B的子类,同时也是类的子类个类是某个类父类的同时,也可以是另一个类的子类。例如上面的示例中,B类是A类的子类,同时又是c类的父类。

重写父类方法

      在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要
对继承的方法进行一些修改,即对父类的方法进行重写。需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型。
       文件4-1中,Dog类从Animal类继承了shout()方法,该方法在被调用时会打印“动物发出叫声”,这明显不能描述一种具体动物的叫声,Dog类对象表示犬类,发出的叫声应该是“汪汪汪”。

09beb350765b4cf2adb77d34ee784f92.png

94153a74398b4c2c8f57d5e144f4edab.png 

 

super关键字
      当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,在Java中专门提供了一个super关键字用于访问父类的成员。例如访问父类的成员变量、成员方法和构造方法。接下来分两种情况来学习一下super关键字的具体用法。
1.使用super关键字访问父类的成员变量和成员方法。具体格式如下:
super成员变里
super成员方法([参数1参数2-1)
2.使用super关键字访问父类的构造方法。具体格式如下:
super([参数1,参数2])
1d62a90947c04f6abe08dc81c0b7d331.png

102f87a726854eb2911aa1d012400dae.png 

 90d6e6ebe6144d919057a09b84d04a0e.png

 例题代码2:

5b51802443994748b05bb1faa4ad035a.png

 

4.2 final关键字
final关键字修饰类

      final关键字可用于修饰类、变量和方法,它有“无法改变”或者“最终的含义,因此被final修饰的类、变量和方法将具有以下特性:
·final修饰的类不能被继承。
·final修饰的方法不能被子类重写。
final修饰的变量(成员变量和局部变量)是量,只能赋值一次。

       Java中的类被final关键字修饰后,该类将不可以被继承,也就是不能够派生子类。

39bf01daaba64f15940d5a182e5332a3.png

 deaae36d0d454929a2283fdd6519f8b6.png

01b9096cfc314e90a7fa731990b3d279.png 

 7ad7969d15c046af9a6c12f6532f78c8.png

 4.3 抽象类和接口

抽象类

       当定义一个类时,常常需要定义一些方法来描述该类的行为特征,但有时这些方法的实现方式是无法确定的。例如前面在定义Animal类时,shout()方法用于表示动物的叫声,但是针对不同的动物,叫声也是不同的,因此shout()方法中无法准确描述动物的叫声。

       针对上面描述的情况,Java允许在定义方法时不写方法体,不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰,具体示例如下:

abstract void shout();//定义抽象方法shout()

      当一个类中包含了抽象方法,该类必须使用abstract关键字来修饰,使用abstract关键字修饰的类为抽象类,具体示例如下:

/定义抽像卖Antmal

abstrect class Animal {

//定义抽象方法shoutli();

abatract int shout();

 

       在定义抽象类时需要注意,包含抽象方法的类必须声明为抽象类,但抽象类可以不包含任何抽象方法,只需使用abstract关键字来修饰即可。另外,抽象类是不可以被实例化的,一因为抽象类中有可能包含抽象方法,抽象方法是没有方法体的,不可以被调用,如果想调用抽象类中定义的方法,则需要创建一个子类,在子类中将抽象类中的抽象方法进行实现。

1b7104f861b84c09b7df1fd34ca0c6ac.png

 b0bd9d3808a24e8ba7cb07c8d424533f.png

 接口

      如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象。

      在定义接口时,需要使用interface关键字来声明,其语法格式如下:

[public] interface接口名extends接口1挤口2....

[public][static][f1na1]数据类型常里名-常里值[public] [abstract] 返回值抽象方法名(数列表)}

       在上面的语法中,一个接口可以有多个父接口,他们之间用逗号隔开。Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口。接口中的变量默认使用“public static final”来修饰,即全局常量;接口中定义的方法默认使用“publicabstract”来修饰,即抽象方法。如果接口声明为public,则接口中的变量和方法全部为public。
       由于接口中的方法都是抽象方法,因此不能通过实例化对象的方式来调用接口中的方法。此时需要定义一个类,并使用implements关键字实现接口中所有的方法。一个类可以在继承的同时实现多个接口,在implements子句中用逗号隔开。接口的实现类声明格式如下:
[<修饰符>]class<类名> [extends<超类名>] [implements <接口1>,<接口2>,.….]
ac75e4f8e0db47c981b029df7cea71b9.png

87cfab14e77c45b7b94274fad1f1dc7a.png 

 

      为了加深初学者对接口的认识,接下来对接口的特点进行归纳,具体如下:
      接口中的方法都是抽象的,不能实例化对象。

       接口中的属性只能是常量。
       当一个类实现接口时,如果这个类是抽象类,则实现接口中的部分方法即可,否则
需要实现接口中的所有方法。
       一个类通过implements关键字实现接口时,可以实现多个接口,被实现的多个接口
之间要用逗号隔开。具体示例如下:

interface Run {
程序代码....

}
interface FLy {
程序代码.....
}
cless Bird implements Run, Fly[
程序代码.......

       一个接口可以通过extends关键字继承多个接口,接口之间用逗号隔开。具体示例如下,
interface running(
程岸代码.....

}
interface flying (
程伴代码.....

}
Interfaoe lating extends runming, fIying {
程伴代明.......

}

      一个类在继承另一个类的同时还可以实现接口,此时,extends关键字必须位于implem关键字之前。

4.4 多态 

多态概念

       在设计一个方法时,通常希望该方法具备一定的通用性。例如要实现一个动物叫的方法,由于每种动物的叫声是不同的,因此可以在方法中接收一个动物类型的参数,当传入猫类对象时就发出猫类的叫声,传入犬类对象时就发出犬类的叫声。在同一个方法中,这种由于参数类型不同而导致执行效果各异的现象就是多态。继承是多态得以实现的基础。

       在Java中为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。

35434668debf45608dad5a8432a6f4c8.png

a807a432ea8249bdb38a067b9b4cb688.png 

eb1ffc1d746b4e9da7695f75131b5e87.png 

0943f8b97d004de592345dc5f6884126.png 

 

多态的类型转换

      在多态的学习中,涉及到将子类对象当作父类类型使用的情况,此种情况在
Java的语言环境中称之为“向上转型”,例如下面两行代码:
Anima1 an1=new Cacil;//将cat对象当作Ani类型来使用

Animal an2=new Dogt://将Dog对象当作Antme类型来便用

     将子类对象当作父类使用时不需要任何显式地声明,需要注意的是,此时不能通过父类变量去调用子类中的特有方法。

3c551fa8993d4df0b10a0b12afe41e31.png

9e3cfc44fb7f4a9895ba4668f7c38348.png 

 

Object类

       在JDK中提供了一个Object类,它是类层次结构的根类,每个类都直接或间接继
承自该类,所有对象(包括数组)都实现了这个类的方法。Object类中的常用方法如下表所示。
    方法名称    方法说明
    equaiso    指示其他某个对象是否与此对象“相等”。
    getClassO    返回此Object的运行时类。
    hashCodeO).    返回该对象的哈希码值。
    toStringO    返回该对象的字符串表示,
 922f2de9008d48c59867d373ae9c9f24.png

 

     在Object类中定义了toString()方法,在该方法中输出了对象的基本信息,Object类的toString()方法中的代码具体如下:

getClas3()getName() +"@”+Integer.toHexString(hashCode());+

     为了方便初学者理解上面的代码,接下来分别对其中用到的方法进行解释,具体如下:
   getClass().getName()代表返回对象所属类的类名,即Animal。
   hashCode()代表返回该对象的哈希值。
    Integer.toHexString(hashCode())代表将对象的哈希值用16进制表示。
      其中,hashCode()是Object类中定义的一个方法,这个方法将对象的内存地址,  返回一个int类型的哈希值。    
cfbef0c2012c4a1fb549caa91db6d1ff.png

79e9e4519dd2474db4f823835992e0bf.png 

 匿名内部类

      在编写Java程序时,在类里面定义的类称之为内部类(InnerClass),内部类是外部类的一个成员。Java内部类可以分为:成员内部类、方法内部类和匿名内部类等。

       在前面多态的讲解中,如果方法的参数被定义为一个接口类型,那么就需要定义一个类来实现接口,并根据该类进行对象实例化。除此之外,还可以使用匿名内部类来实现接口。所谓匿名内部类就是没有名字的内部类,表面上看起来它似乎有名字,实际那不是它的名字。当程序中使用匿名内部类时,在定义图名内部类的地方往往直接创建该类的一个对象。

2f5781627f3844109d5083beea75ddaa.png

3a378dce60904440b6658f99c9335140.png 

4f07090c84cd4a56934be5678cc87741.png 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值