-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
面向对象是Java学习中非常重要的部分,这是Java与其他编程语言设计思想的不同,因此必须要理解与掌握。
一、什么是面向对象?
面向对象是一种思想,是基于面向过程而言的,面向过程强调的是功能行为,而面向对象将功能封装进对象,强调的是具备了功能的对象。也就是说,面向对象就是把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。
示例:把大象装进冰箱
面向过程为:打开冰箱——>把大象装进冰箱——>关闭冰箱。
面向对象为:冰箱打开——>冰箱存储——>冰箱关闭。
从上面示例中可以看出,面向过程像是自己亲自在操作,而面向对象像是指挥别人操作。面向过程强调了自己去打开冰箱、把大象装进冰箱并关闭冰箱,而面向对象则将这些动作封装成一个对象,即冰箱,再指挥冰箱去完成打开、存储、关闭动作。面向对象将自己从执行者变成了指挥者,把复杂的事情简单化,这是面向对象中的一个很重要的特点。
二、面向对象的特点
1.比较符合人的思考方式。
2.将自己从执行者便成了指挥者,从而把复杂的事情简单化。
三、对象与类
1.什么是类?
类就是对现实事物的描述,在Java中类是具体事物的抽象。
2.类的特点
1)类中的大多数数据,只能用本类的方法进行处理。
2)类class用来描述对象的属性和行为,其中属性是指对应类中的成员变量,行为是指对应类中的成员方法。定义类其实就是在定义类中的成员(成员变量和成员函数)。
3.类与对象的关系?
类是对同类对象抽象出其共性而形成,对象是该类实实在在存在的个体。在Java中,类就是用class定义的类,而对象就是用new建立在堆内存中的实体。现在通过一个简单的示例来进行理解:
在这幅图中,类就表示图纸,而汽车就是对象。
4.匿名对象
1)定义:匿名对象是指没有建立对象的引用的对象,它是对象的简化形式。例如:new car ()。
2)匿名对象的两种使用情况:
a)如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
b)将匿名对象作为实参传递给一个方法调用。
注:如果对一个对象进行多个成员调用,必须给这个对象起个名字。
5.成员变量与局部变量
1)成员变量:
定义:直接定义在类中的变量或属性,就称为成员变量。
种类:分为类变量和实例变量。
如果该成员变量有 static 关键字修饰,则该成员变量称为 静态变量 或 类变量。
如果该成员变量没有 static 关键字修饰,则该成员变量被称为 非静态变量 或 实例变量。
类变量(或静态变量)的特点:
a)定义在类中,在整个类中都可以被访问。
b)类变量随着类的加载而存在于方法区中。
c)有默认初始化值。
d)类变量生命周期最长,随着类的消失而消失。
注:类变量可以直接用类名调用,且只能被初始化一次。
实例变量(或非静态变量)的特点:
a)定义在类中,在整个类中都可以被访问。
b)实例变量随着对象的建立而存在于堆内存中。
c)实例变量生命周期随着对象的消失而消失。
d)有默认初始化值。
2)局部变量:
定义:指在形参、方法内及代码块中定义的变量。
特点:
a)局部变量只定义在局部范围内,如:函数内,语句内等。
b)局部变量存在于栈内存中。
c)作用的范围结束,变量空间会自动释放。
d)局部变量没有默认初始化值。
1.构造函数
1)定义:与类名称具有一样名称的成员函数。
2)格式:
class 类名
{
类名 ()
{
super();//默认构造函数里有一句隐式的super语句
}
}
注:该格式为默认构造函数形式,也可自定义构造函数或者重载构造函数。
3)特点:
a) 函数名与类名相同。
b) 如果类中没有定义构造函数,则系统会默认一个空的构造函数。这个默认的构造函数的权限和所属类一致,如果类被public修饰,则默认构造函数也带public修饰,反之一样。
c) 不用定义返回值类型,不可以写return语句。
d)可以通过重载形式自定义构造函数,这时系统默认的空的构造函数不存在。
e)构造函数内的第一行如果没有super语句,则系统默认会定义一个super()语句,用来指向父类的构造函数,以便让父类先进行初始化。
4)作用:给对象进行初始化。 5)继承特性:a)子类只继承父类的默认(缺省)构造函数,即无形参构造函数。如果父类没有默认构造函数,那子类不能从父类继承默认构造函数。
b)子类从父类处继承来的父类默认构造函数,不能成为子类的默认构造函数。
c)在创建对象时,先调用父类默认构造函数对对象进行初始化,然后调用子类自身自己定义的构造函数。
d)如果子类想调用父类的非默认构造函数,则必须使用super来实现。
e)子类必须调用父类的构造函数。系统会自动调用父类的默认构造函数,如果父类没有默认构造函数时,子类构造函数必须通过super调用父类的构造函数。
6)问题思考:
a)什么时候定义构造函数?
当分析事物时,该事物存在时就需具备一些特性或者行为,那么将这些内容定义在构造函数中。
b)构造函数和一般函数有什么区别?
—写法上不同:构造函数只有函数名且同类名一致,而一般函数有返回值类型且不能与类名一致。
—运行上不同:构造函数式在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,给是对象添加对象具备的功能。一个对象建立,构造函数只运行一次。而一般方法可以被该对象调用多次。2.构造代码块
1)定义:在Java中,使用”{}”括起来的代码称为代码块,而直接定义在类中的代码且无任何声明,就称为构造代码块。
2)格式:
class 类名
{
{
构造代码块语句;
}
}
3)特点:
a)构造块会重复的调用多次。
b)构造块优先于构造方法。 4)作用:给对象进行初始化。 5)问题思考: a)构造代码块与构造函数有什么区别? 构造代码块是给所有对象进行初始化,而构造函数是给对应的对象初始化。 b)构造代码块里可以定义那些语句或元素?3.静态代码块 1)定义:直接定义在类中,且使用Static声明的代码块,叫做静态块。 2)格式: class 类名 { static { 静态代码块语句; } } 3)特点:随着类的加载而执行,只有用到类中的内容才会被加载。只执行一次,并优先于主函数。用于给类进行初始化。 注:特殊情况,如 Person(类)per = null,编译可通过,但没有加载类。 4)作用:用于给类进行初始化。
4.主函数——main 1)概念:是一个特殊的函数,作为程序的入口,可以被Jvm调用。 2)格式: public static void main(String [ ] args) { 主函数的语句; } 3)主函数各关键字解释: public:代表这该函数访问权限是最大的。 static:代表主函数随着类的加载 就已经存在了。 void:主函数没有具体的返回值。 main:不是关键字,但是是一个特殊的单词,可以被Jvm识别。 (String[] arr):函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。 注:主函数是固定格式的,用于被Jvm识别。 4)问题思考: a)Jvm在调用主函数的时候,给主函数传入了什么? Jvm在调用主函数时,给主函数传入了 new String[0]. b)可不可以自定义给主函数传值?如果可以,如何传? 可以自定义给主函数传值,但必须在执行java命令的时候进行传值,示例:java 类名 元素1 元素2 ..... 注:元素1、元素2等都为自定义传入的值,必须为字符串类型,因为主函数只接受字符串类型。
4.关键字——static 1)什么是static? static是一个修饰符,用于修饰成员,即成员变量和成员函数。当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直 接被类名调用。格式为:类名.静态成员。 2)特点:
a)随着类的加载而加载,随着类的消失而消失 ,生命周期最长。
b)优先于对象存在,即静态先存在,对象后存在。
d)可以直接被类名所调用。
e)静态方法只能访问静态成员,即静态方法里不能出现非静态成员变量和非静态成员方法。
3)利弊:
利处:对对象共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份,可以直接被类名调用。
弊端:生命周期过长,只能访问静态,因为静态优先于对象建立。
4)问题思考
a)类名调用和new对象有什么区别?
类名调用只能调用类中的静态成员变量和静态方法,并且是非私有的,类名调用只进行类初始化,即只加载类*享数据,也就是被static所修饰的成员。
new对象即完成了类*享数据的加载,也完成了对象特有数据的加载或者初始化。
b)什么时候定义静态变量或类变量?
当对象中出现共享数据时,该数据被静态所修饰,则定义成静态。
c)什么时候定义静态函数?
当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
d)为什么静态方法中不可以定义this,super关键字?
因为静态优先于对象存在,所以静态方法中不可以出现this、super关键字。
5)静态应用
工具类帮助文档应用示例:
/*
静态的应用:工具类
每一个应用程序中都有共性的功能,可以将这些功能进行抽取
,独立封装,以便复用。
虽然可以通过建立ArrayTool的对象使用这些工具方法,对数组进行操作。
发现问题:
1.对象是用于封装数据的,可是ArrayTool对象并未封装特有数据。
2.操作数组的每一个方法都没有用到ArrayTool对象中的特有数据。
这时就考虑,让程序更严谨,是不需要对象的。
可以将ArrayTool中的方法都定义成静态的,直接通过类名调用即可。
当方法都静态后,可以方便与使用,但是该类还是可以被 其它程序
建立对象,为了更为严谨,强制让该类建立对象,可以通过让构造
函数私有化。
制作程序的说明书,java的说明书通过文档注释完成。
*/
/**
这是一个可以对数组进行操作的工具类,该类中提供了获取最值、排序
等功能。
@author 李四
@version V1.1
*/
public class ArrayTool
{
private ArrayTool(){};
/**
获取一个整形数组中的最大值。
@param arr 接受一个int类型的数组。
@return 会返回一个该数组中的最大值。
*/
public static int getMax(int[] arr)
{
int max=0;
for (int x=1;x<arr.length ;x++ )
{
if(arr[x]>arr[max])
max=x;
}
return arr[max];
}
/**
获取一个整形数组中的小值。
@param arr 接受一个int类型的数组。
@return 会返回一个该数组中的最小值。
*/
public static int getMin(int[] arr)
{
int min=0;
for (int x=1;x<arr.length ;x++ )
{
if(arr[x]<arr[min])
min=x;
}
return arr[min];
}
/**
给int数组进行选择排序。
@param arr 接受一个int类型的数组。
*/
public static void selectSort(int[] arr)
{
for (int x=0;x<arr.length ;x++ )
{
for (int y=x+1;y<arr.length ;y++ )
{
if(arr[x]<arr[y])
{
swap(arr,x,y);
}
}
}
}
/**
给int数组进行冒泡排序。
@param arr 接受一个int类型的数组。
*/
public static void bubbleSort(int[] arr)
{
for (int x=0;x<arr.length-1 ;x++ )
{
for (int y=0;y<arr.length-x-1 ;y++ )
{
if(arr[y]<arr[y+1])
swap(arr,y,y+1);
}
}
}
/**
给int数组中的元素进行位置置换。
@param arr 接受一个int类型的数组。
@param a 要置换的位置。
@param b 要置换的位置。
*/
private static void swap(int[] arr,int a,int b)
{
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
/**
用于打印数组中的元素,打印形式是:[element1,element2, ...]。
@param arr 接受一个int类型的数组。
*/
public static void printArray(int [] arr)
{
System.out.print("[");
for (int x=0;x<arrr.length ;x++ )
{
if(x!=arr.length-1)
System.out.println(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
在dos命令行中输入:javadoc -d 存放的目录 -author -version ArrayTool.java
Java中的javadoc工具就会自动完成工具类说明文档的制作,也称API的制作。
如图所示:
下面就是工具类的API文档:
5.关键字——this
1)如何理解this关键字?
this关键字代表本类对象,那个对象调用this所在函数,this就代表哪个对象。
2)this语句的特点:
a)用于构造函数之间进行互相调用。如:this(name)。
b)this语句只能定义在构造函数的第一行,因为初始化要先执行。
3)this关键字的应用:
a)当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中的成员变量(this是当前对象自己)。
b)把自己当作参数传递时,也可以用this.(this作当前参数进行传递)。
c)有时候,我们会用到一些内部类和匿名类,如事件处理。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。
d) 在构造函数中,通过this可以调用同一类中别的构造函数。
6.关键字——final
1)什么是final关键字?
final(最终)是一个修饰符,可以修饰类,函数,变量。
2)特点:
a)被final修饰的类不可以被继承,被final修饰的方法不可以被覆盖。
b)被final修饰的变量是一个常量,并且只能赋值一次,final即可以修饰成员变量,也可以修饰局部变量。
c)final用于修饰一些固定不变的数据,增强阅读性。被fanal修饰常量,常量名单词全部大写,如果由多个单词组成,则单词之间用_连接。如果在final前还有static和public修饰,则该常量称为全局常量。
7.对象的初始化过程
1)把类名.class文件加载到内存中。
2)执行该类中的static代码块,如果有得话,给该类进行初始化。
3)在堆内存中开辟空间,分配内存地址。给对象。
4)在堆内存中建立对象的特有属性。并进行默认初始化。
5)对属性进行显示初始化。
6)对对象进行构造代码块初始化。
7)对对象进行对应构造函数初始化。
8)将内存地址赋给栈内存中的对象名变量。