面向对象基础篇
一、概念
面向对象是相对面向过程而言,面向对象和面向过程都是一种思想。
面向过程:
强调的是功能行为。代表语言:C语言。
例子:把大象装进冰箱
1. 打开冰箱。
2. 存储大象。
3. 关上冰箱。
“打开”、”存储”、”关上”都是功能行为,在代码中的直观体现就是函数或者方法,这就是一种面向过程的以功能行为为主体的思想体现。
面向对象:
将功能封装进对象,强调具备了功能的对象。代表语言:Java、C++、C#。
例子:把大象装进冰箱
1. 冰箱打开。
2. 冰箱存储。
3. 冰箱关闭。
可以看到,所有的操作都是以”冰箱”为主体,而不是功能行为。也就是说冰箱自己已经具备”打开”、”存储”、”关上”的行为功能,我们只需要让冰箱执行它具备的功能就可以了。这就是一种面向对象的以执行功能的对象为主体的思想体现。
二、特点
是一种符合人们思考习惯的思想,可以将复杂的事情简单化,将程序员从执行者转换成了指挥者。
完成需求时:
1. 先要去找具有所需功能的对象来用。
2. 如果该对象不存在,那么创建一个具有所需功能的对象。
这样可以简化开发并提高复用。
三、面向对象开发、设计和特征
开发的过程:
就是不断的创建对象,使用对象,指挥对象做事情。
设计的过程:
就是在管理和维护对象之间的关系。
面向对象的特征:
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
四、类与对象的关系
使用计算机语言就是不断地在描述现实生活中的事物。
java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义。
对象即是该类事物实实在在存在的个体。
对于同一类事物可以抽取它们的共性的内容,定义在类中。如:生活中的汽车,每一台车都有轮胎数和颜色。那么在通过java描述汽车这类事物时,就可以将这两个共性属性作为类中的属性进行定义。通过该类建立的每一个汽车实体都具有该属性,并可以有对象特有的属性值。
类的定义:描述事物的属性和行为。如:人有身高,体重等属性,有说话,打球等行为。
Java中用类class来描述事物也是如此。
属性:对应类中的成员变量。
行为:对应类中的成员函数。
定义类其实在定义类中的成员(成员变量和成员函数)。
那么成员变量和局部变量有什么不同呢?
成员变量:
1. 成员变量定义在类中,在整个类中都可以被访问。
2. 成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
3. 成员变量有默认初始化值。
局部变量:
1. 局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
2. 局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
3. 局部变量没有默认初始化值。
五、匿名对象
匿名对象是对象的简化形式。
匿名对象两种使用情况:
1. 当对对象方法仅进行一次调用时;
2. 匿名对象可以作为实际参数进行传递。
示例:
class Car
{
String color = "red";
int num = 4;
public static void run()
{
System.out.println("function run is running!" );
}
}
class CarDemo{
public static void main(String[] args){
//对对象方法仅进行一次调用时,就可以使用匿名对象
new Car().run();
//匿名对象可以作为实际参数进行传递
show(new Car());
}
public static void show(Car c){
c. num = 3;
c. color = "black" ;
System.out.println("function show is running!" );
System.out.println(c.num + "..." + c. color);
}
}
ps:在java中,方法参数的传递永远都是传值,而这个值,对于基本数据类型,值就是你赋给变量的那个值。而对于引用数据类型,这个值是对象的引用,而不是这个对象本身。
六、封装
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
1. 将变化隔离。
2. 便于使用。
3. 提高重用性。
4. 提高安全性。
封装原则:
1. 将不需要对外提供的内容都隐藏起来。
2. 把属性都隐藏,提供公共方法对其访问。如,getXXX,setXXX。
示例:
/*
人:
属性:年龄
行为:说话
*/
class Person{
//private:私有,是一个权限修饰符,用于修饰
//不希望别人直接访问赋值,需要通过私有化把属性进行隐藏
private int age ;
//通过提供set、get公共方法对其访问
public void setAge( int a){
//在set方法内可以对属性的赋值进行限制
if (a > 0 && a < 130){
age = a;
} else
System.out .println("错误的数据" );
}
public int getAge(){
return age ;
}
void speak(){
System.out .println("age = " + age);
}
}
class PersonDemo{
public static void main(String[] args){
Person p = new Person();
//通过其他方式访问
p.setAge(20);
p.speak();
//赋值不合法,set方法就不允许成功赋值
p.setAge(-20);
}
}
运行结果:
age=20
P.S.
1、私有仅仅是封装的一种体现而已。
2、private关键字:是一个权限修饰符,用于修饰成员(成员变量和成员函数),被私有化的成员只在本类中有效。
3、常用场景之一:将成员变量私有化,对外提供对应的set、get方法对其进行访问,提高对数据访问的安全性。
七、构造函数
特点:
1、函数名与类名相同。
2、不用定义返回值类型。
3、没有具体的返回值。
PS: 在构造函数前面加上返回值就只是一般函数了。
作用:给对象进行初始化。
示例:
class Person{
private String name ;
private int age ;
//定义一个Person类的构造函数
//构造函数,而且是空参数的
Person(){
System.out.println("person run");
}
public void speak(){
System.out.println(name + ":" + age);
}
}
class ConsDemo{
public static void main(String[] args){
//构造函数:构建创造对象时调用的函数
//作用:可以给对象进行初始化
Person p = new Person();
p.speak();
}
}
运行结果:
person run
null:0
那么问题来了
1、一般函数和构造函数什么区别呢?
构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。
一般函数:对象创建后,需要函数功能时才调用。
构造函数:对象创建时,会调用并且只调用一次。
一般函数:对象创建后,可以被调用多次。
2、创建对象都必须要通过构造函数初始化。
一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数。
如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。
3、多个构造函数是以重载的形式存在的。
示例:
class Person{
private String name ;
private int age ;
Person(){
name = "baby" ;
age = 1;
System.out.println("person run");
}
//如果有的孩子一出生就有名字
Person(String n){
name = n;
}
//如果有的孩子一出生就有名字和年龄
Person(String n, int a){
name = n;
age = a;
}
public void speak(){
System.out.println(name + ":" + age);
}
}
class ConsDemo{
public static void main(String[] args){
Person p1 = new Person();
p1.speak();
Person p2 = new Person("小李" );
p2.speak();
Person p3 = new Person("小张" ,10);
p3.speak();
}
}
运行结果:
person run
baby:1
小李:0
小张:10
八、this关键字
定义: this代表其所在函数所属对象的引用。换言之,this代本类对象的引用。
用途:当成员变量和局部变量重名,可以用关键字this来区分,this就是所在函数所属对象的引用。
简单说,哪个对象调用了this所在的函数,this就代表哪个对象。一般方法调用默认加this。
什么时候使用this关键字呢?
当在函数内部需要用到调用该函数的对象时,就用this。
(简言之:本类功能内部用调用本类对象时,用this)
示例:
class Person{
private String name ;
private int age ;
Person(String name){
//通过this区分成员变量和局部变量
this.name = name;
}
Person(String name, int age){
//this也可以用于在构造函数中调用其他构造函数
this(name);//初始化赋值必须先执行,;因此要放在构造函数的第一行,否则报错
this.age = age;
}
public void speak(){
System.out.println(name + ":" + age);
}
}
class ConsDemo{
public static void main(String[] args){
Person p1 = new Person("lisi" );
p1.speak();
Person p2 = new Person("zhangsan" ,30);
p2.speak();
}
}
运行结果:
lisi:0
zhangsan:30
注意:通过this在构造函数中调用其他构造函数的时候,只能定义在构造函数的第一行,因为初始化动作要先执行,否则就会报错。
this关键字的使用示例:
class Person{
private String name ;
private int age ;
Person(String name, int age){
this.name = name;
this.age = age;
}
/*
判断是否是同龄人
*/
public boolean compare(Person p){
return this.age == p.age;//这里用到了this关键字表示本人,和另一个人进行年龄的比较
}
}
class compareDemo{
public static void main(String[] args){
Person p1 = new Person("lisi" ,20);
Person p2 = new Person("zhangsan" ,20);
System.out.println(p1.compare(p2));
}
}
运行结果:
true