一、面向对象的概念:
1、面向对象是相对面向过程而言,都是一种思想。
- 面向过程:强调的是功能行为。(执行者)
- 面向对象:将功能封装进对象,强调具备了功能的对象。(指挥者)
面向对象是基于面向过程的。
2、面向对象的三大特征:
封装性、继承性、多态性
3、类和对象的关系:
类:就是对现实生活中事物的描述,是具体事物的抽象。
对象:就是这类事物实实在在存在的个体。
图例:
4、类和对象在Java中的体现:
- 类映射到Java中,描述就是用class定义的类。
- 具体的对象就是对应Java在堆内存中用new建立的实体。
5、类的定义:
①.生活中描述事物无非就是描述事物的属性和行为。
②.其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量、成员函数)。
属性:对应类中的变量。
行为:对应类中的方法(函数)。
6、成员变量和局部变量的区别:
按存储区域分:局部变量存放在栈内存中,全局变量存放在堆内存中。
按作用域分:局部变量作用于函数或者语句中,全局变量作用于整个类中。
7、对象的创建和属性、方法的访问:
【对象创建格式】类名对象名称 = new类名();
【属性访问格式】对象名称.属性名
【方法访问格式】对象名称.方法名
代码示例:
class Car //定义一个类Car,用于描述汽车。
{
//描述汽车颜色。
String color = "红色";
//描述轮胎数。
int num = 4;
//运行行为。
void run()
{
System.out.println(color+"..."+num);
}
}
class CarDemo
{
public static void main(String[] args)
{
//生产汽车。在java中通过new操作符来完成。
//其实就是在堆内存中产生对象实体。
Car c = new Car(); //c就是一个类类型变量。记住:类类型变量指向对象。
c.color = "bule"; //将汽车颜色改为蓝色。
c.run(); //调用汽车的run方法。
Car c1 = new Car();
c1.run();
}
}
对象的内存结构:
8、匿名对象:就是没有名称的对象。是对象的简化形式。
特点:只在堆内存中开辟空间,而不再栈内存中进行引用。
①.创建格式:new类名();
②.调用成员格式:new类名().属性名
new类名().方法名
③.匿名对象的两种使用情况:
A.当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。
示例:new Car().color = “blue”; //没有实际意义,执行完之后就变成了垃圾对象。
注:如果对一个对象进行多个成员调用,必须给这个对象起个名字。
B.可以将匿名对象做为实际参数进行传递。
示例:show(new Car());
注:当被调用的的方法接收一个匿名对象的参数,运行完了之后,堆内存中的匿名对象空间就成了垃圾对象,等待被回收。
二、封装(Encapsulation)
1、封装:是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式。(对外部不可见)
2、好处:
- 将变化隔离。
- 便于使用。
- 提高重用性。
- 提高安全性。
3、封装原则:将不需要对外提供的内容都隐藏起来,仅提供对外访问的方式。
注:之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句。对访问的数据进行操作,提高代码健壮性。
4、private(私有):权限修饰符,用于修饰类中的成员(成员变量,成员函数)。
注:被私有化的成员只在本类中有效。
***强调:封装不是私有。私有仅仅是封装的一种表现形式。
5、setter和getter方法:用于设置和获取被封装的属性信息。还可以在setter方法中加入检测代码用于达到一定的控制目的。
代码示例:
class Person{
private int age; //定义并私有化年龄属性。
public void setAge(int a){ //用于设置年龄。
if(age>0 &&age<130){ //检测代码,用于控制设置的年龄范围。
age = a;
speak();
}
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.age = 20;
p.setAge(-20);
}
}
三、构造函数
1、特点:
①.函数名和类名相同。
②.无返回值类型。
注意:不需要返回值类型和void的完全是两码事:
void:是一种返回值类型,代表没有具体结果返回的情况。
无返回值类型:根本就不需要定义返回值类型。
③.不可以写return语句。
2、作用:给对象进行初始化。(其实就是在给类中的属性初始化)
对象一建立,就会调用与之对应的构造函数。
3、构造函数的小细节:
①.当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。
②.在一个类中如果已经明确的声明了一个构造方法,那么程序在编译时将不会再生成默认的构造方法,即一个类中应保证至少有一个构造方法。
4、构造方法和一般方法的区别:
①.写法上不一样。
②.在运行上不同。
A.构造方法是在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,是给对象添加对象具备的功能。
B.一个对象建立,构造方法只运行一次。而一般方法可以被该对象调用多次。
5、什么时候定义构造函数呢?
当分析事物时,该事物一存在就具备一些特性或者行为,那么就将这些内容定义在构造函数中。
6、构造函数的权限问题:一个类中默认会有一个空参数的构造函数,这个默认的构造函数的权限和所属类一致。
如果类被public修饰,那么默认的构造函数也带public修饰符。
如果类没有被public修饰,那么默认的构造函数也没有public修饰符。
总结一句话:默认构造函数的权限是随着类的变化而变化的。
7、默认构造函数和空参数构造函数的区别:
默认构造函数:每个类中都自带的不可见的(隐式的)构造函数。
空参数构造函数:和默认构造函数是两码事,是程序开发人员写出来的,可见。
四、构造代码块
1、代码块:指用一对大括号{ }括起来的一段代码。
根据位置以及声明关键字的不同,可以分为普通代码块、构造代码块、静态代码块和同步代码块4种。
- 普通代码块:就是指直接在方法或者语句中定义的代码块。
- 构造代码块:是指写在类中的代码块。
- 静态代码块:是指使用static关键字声明的代码块。
- 同步代码块:在代码块前加上 synchronized关键字,则此代码块就成为同步代码块。
2、构造代码块:
①.作用:和构造函数一样,都是给对象进行初始化的。
②.特点:对象一建立就运行,并且优先于构造函数执行。
③.和构造函数的区别:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象进行初始化。
注:构造代码块中定义的是不同对象共性的初始化内容。
3、代码示例:
class Person
{
private String name;
private int age;
//构造代码块。
{
System.out.println("cyr..."); //定义不同对象共性的初始化内容。只要new一个对象,就执行该代码块一次,输出cry...
}
Person() //定义空参数的构造方法。
{
System.out.println("A:name="+name+"...age="+age);
}
Person(String n) //定义有一个参数的构造方法
{
name = n;
System.out.println("B:name="+name+"...age="+age);
}
Person(String n,int a)
{
name = n;
age = a;
System.out.println("C:name="+name+"...age="+age);
}
}
class PersonDemo2
{
public static void main(String[] args)
{
Person p1 = new Person(); //创建一个对象,调用空参数的构造方法。
Person p2 = new Person("lisi"); //创建对象调用有一个参数的构造方法并初始化。
}
}
运行结果:
cyr...
A:name=null...age=0
cyr...
B:name=lisi...age=0
/*每创建一个对象,就先执行一次构造代码块,再执行构造函数进行初始化属性*/
五、this关键字
1、this代表的是什么?
this代表本类的对象。到底代表哪一个对象呢?
this代表它所在函数所属对象的引用。
简单说:哪个对象在调用this所在的函数,this就代表哪个对象。
2、在一个类中,成员之间相互调用的时候,其实都是对象来完成的。
例如:下面的示例中speak方法调用show方法,默认是省略了show方法前面的this.。如果对象p调用speak方法,则show方法也是对象p在调用,其它对象也同理。
代码示例:
class Person
{
private String name;
private int age;
Person(String name)
{
this.name = name; //此处的this.就是调用该构造方法的对象,相当于p.name= name;
}
public void speak()
{
System.out.println("name="+this.name+"...age="+this.age);
show(); //调用show本类中的show方法,前面默认省略了this.
}
public void show()
{
System.out.println(this.name);
}
}
class PersonDemo3
{
public static void main(String[] args)
{
Person p = new Person("lisi"); //该对象一创建,就调用构造方法并初始化name的值。
Person p1 = new Person("zhangsan");
p.speak();
p1.speak(); //当对象p1调用speak方法时候,打印语句中的this.name和this.aga中的this.就表示该对象。
}
}
3、this的基本应用:当定义类中功能时,该函数内部要用到该调用该函数的对象时,这时用this来表示这个对象。
一句话:但凡本类功能内部使用了本类对象,都用this表示。
代码示例:
/*
需求:给人定义一个用于比较年龄是否相同的功能。也就是是否是同龄人。
*/
public boolean compare(Person p)
{
return this.age==p.age; //使用this.表示调用此函数的对象,用于区分同名对象。
}
4、this关键字在构造函数间的应用:
①.构造函数间调用,只能用this语句。
②.this语句只能定义在构造函数的第一行。因为初始化动作要先执行。
代码示例:
class Person
{
private String age;
private int age;
Person(){}
Person(String name)
{
this(); //this语句表示调用空参数的构造方法。且必须要放在构造函数的第一行。
this.name = name;
}
Person(String name,int age)
{
this(name); //此处this语句表示调用有一个参数的构造方法。
this.age = age;
}
}
③.this调用构造方法时,程序中至少要存在一个构造方法不使用this调用其它构造方法。
因为:都互相调用的话容易出现“死循环”,程序会报错。
代码示例:
class Person
{
private String age;
private int age;
Person()
{
this("zhangsan"); //此处this语句调用有一个参数的构造方法。
}
Person(String name)
{
this(); //此处this语句调用无参数的构造方法。
}
}