一,Java面向对象概述
1.1 面向对象和面向过程的区别
- 面向过程编程:
强调的是功能行为,体现的思路是一个功能是由一系列明确的有顺序的实现步骤来完成的。因为逻辑更抽象,代码运行的更快,一般使用在底层比较需要性能的功能性场所。 - 面向对象编程:
将功能封装进对象,强调具备了功能的对象。因此,编程时在脑海中抽象出来的是一个个鲜活的对象。这种思想更加强调运用人类在日常的思维逻辑中采用的思想方法与原则。因为跟人的思维贴合的近,从而使编程思路更简单。与面向过程相比,代码运行的效率较慢,但是因为其更好的抽象,便于实现复杂逻辑,一般用来实现业务逻辑。
1.2 面向对象与Java的关系
- Java中的数据交互可以看做是对象与对象之间的交互。
- Java类及其拥有的类成员:属性,方法,构造器,代码块,内部类,这些可以看做一个鲜活对象所具有的功能。
- 面向对象的三大特性:封装性,继承性,多态性,(抽象性),便于对象与对象之间的分隔与联系。
- 涉及的常用关键字:this,package,import,super,static,final,abstract,interface…
1.3 类与类的关系
关联关系
类似老师,学生,学校之间的关系
老师教学生,学生师从老师,而他们都属于学校。三者之间相互关联。继承
继承父类的功能,在此基础上,衍生出更有个性与特色的功能。
类似运动员衍生出球类运动员,再衍生出篮球运动员。篮球远动员具有运动员与球类运动员所有的功能。聚合(聚集,组合)
如果把人的每一个器官看做一个对象,那么他们聚集在人体,组合成一个人。
即为:多个不同种类的对象聚集在一个,组合成一个新的对象。
二 Java中一个对象所具有的东西
2.1 包结构定义(package import):
- 一个对象必定定义在一个类文件中,而一个类文件存在于某一包中,所以有了包结构声明,Java虚拟才知道类定义在哪个地方。
- 在Java文件开头使用 “package”语句来声明源文件所在的包。
- 如果想用其他包里的类,需要使用“import”语句来声明你要使用的类的具体位置:
- 显式导入指定包下的类或接口,默认导入了java.lang.;包含System,String,Math等
- 同名不同包的类导入,除了import声明的类作为默认类,其他用绝对路径,
- 如:java.sql.Date d=new java.sql.Date();
- import static:
表示导入指定类的static属性或方法,如:import static java.lang.System.out;
2.2 类的变量:
变量除了基本数据类型与引用数据类型这种按照变量类型来分,还有按照在类中定义位置类划分的的另一种分类,
即为成员变量,局部变量:
下面来比较一笑成员变量和局部变量的异同:
相同点:
- 声明格式相同,如 int a =0;
不同点:
- 声明位置不同:
成员变量:在类里,方法外。
局部变量:在方法内,方法形参,代码块内 - 成员变量的修饰符有四个:public private protected 缺省
局部变量没有修饰符,与所在方法修饰符相同 - 初始化值:
成员变量有默认的初始化值,0,0.0, ,false,null
局部变量一定要显式赋值,没有默认值。 - 成员变量存在于堆中,局部变量存在于栈中
2.3 类成员之一:属性:
属性就是上面2.2说到的成员变量,类对象的属性赋值的顺序:
1. 属性的默认初始化
2. 属性的显式赋值或代码块初始化(两者按顺序执行)
3. 构造器赋值
4. 对象.方法()赋值
2.4 类成员之二:方法(提供某种功能的实现):
- 方法定义格式:权限修饰符 返回值类型 方法名(形参列表)。
- 除了返回值为void的方法,其他方法都有返回值。
- 方法内可以调用本类的属性,方法。不能在内部定义方法。
- 可变个数的形参的方法:
public void aaBb(int a ,String ... args){}
- 格式:数据类型 … 形参名
- 与同名方法构成重载
- 形参在调用时,个数从零开始,到无穷多个
- 使用可变个数的形参与使用形参数组是一致的
- 形参有不同类型,可变个数形参写在最后
- 一个方法中,最多一个可变个数形参
- 方法的参数传递:
- 形参:方法声明时,小括号内的参数
实参:调用方法时,实际传入的参数的值 - 规则:java中的参数传递机制:值传递机制
①形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量
②形参是引用数据类型的:将实参的堆空间首地址值传递给形参的
- 形参:方法声明时,小括号内的参数
- main方法:
可输入字符串数组,可当作一般方法 - 方法的重载(overload)
- 在同一个类中
- 方法名相同
- 方法的参数列表不同
- 与返回值类型无关
//此两个方法构成重载
max(int a,int b)
max(double a,double b)
当输入int数据时,调用max(int a,int b)
当max(int a,int b)被注释,输入int数据时,也可调用max(double a,double b)
2.5 类成员之三:构造器(constructor)
作用:创建对象,给创建的对象属性赋值
- 设计类时,若不显式的声明类构造器,默认空参构造器。
- 一旦显式定义构造器,默认构造器将不提供。
- 如何声明构造器:权限修饰符 类名(形参){}
- 类的多个构造器之间构成重载
2.6 类成员之四:初始化块(只能用static或者不用static修饰)
1.不用staitc修饰:非静态代码块,可以对类的属性进行初始化操作
里面可以有输出语句
可以有多个代码块,顺序执行
每创建一个对象,非静态代码块加载一次
执行早于构造器
2.static修饰:静态代码块
随着类的加载而加载
只加载一次
多个顺序执行
静态代码块中只能执行静态结构
2.7 类的成员之五:内部类
说明:在类的内部定义类
- 成员内部类:跟方法并列,类似于一个属性
- 外部类的成员:权限修饰符(4个),static,final
- 可以调用外部类的属性方法
- 局部内部类:声明在方法里
关于内部类,需要掌握三点
- 第一点:如何创建成员内部类对象:
- 对于静态成员内部类,可直接创建
- 对于非静态的内部类,通过对象创建
Person.Bird b=new Person.Bird();//可直接创建
Person p=new Person();//通过对象创建
Person.Bird b=p.new Bird();
- 第二点:如何区分调用内部类,外部类的变量(尤其是变量重名时):
内部类变量:this.name;
外部类变量:Person.this.name;
class Person{
private name;
private class Bird{
private name;
//Person.this.name
}
}
- 第三点:局部内部类的使用:常常使用方式为定义一个方法,使其返回值为某个类或实现某个接口的对象,而这个类或接口在方法内部创建
public Comparable getComparable(){
return new Comparable(){
//此处为接口Comparable的重写方法
};
}
关于内存中数据存储结构划分:
- 栈(stack):局部变量,对象的引用名,数组的引用名
- 堆(heap) :new出来的东西(如:对象的实体,数组的实体),含成员变量
- 方法区 :字符串常量(方法,包名,类名等)
- 静态域 :声明为static的变量
三、Java中面向对象具有的特性
3.1 面向对象的特性之一:封装
3.1.1 封装的作用
- 有时候我们只需要知道这个类有什么功能,而不需要知道具体这个类怎么实现的。
- 为了保护属性的私密性,不允许通过对象直接操作属性,而是通过 对象.方法 来控制对象对属性的访问。这样方法内部可以控制对属性的要求的过滤,避免将属性直接设置成非法参数。
- 实现方法:将类的属性私有化,提供公共方法(setter getter),来实现调用
3.1.2 使用什么来实现封装性
使用权限修饰符:修饰属性和方法,从而设置属性和方法的可见性。
可见性优先级 | 修饰符 | 说明 |
---|---|---|
1 | public | 任何地方,跨包可见 |
2 | protected | 包内和缺省相同,包外子类才可见 |
3 | 缺省 | 本包内可见 |
4 | private | 只能本类中 |
3.2 面向对象特性之二:继承(extends)
说明:继承,即子类继承父类,继承之后具有父类相同的功能,并且可以对其功能做一些个性定制,如重写某个方法。
- 实现形式class A extends B{}
- A:子类 B:父类(基类,SuperClass)
- 子类继承父类后,父类中声明的属性,方法,子类可以获取到。
- 当父类有private的属性或方法时,子类同样可以获取到,只是由于封装性,子类无法直接调用。
- 子类通过继承获取父类的结构外,还可以定义自己特有成分。
- java的继承性只支持单继承(只能继承一个父类),如果需要多个功能,可以实现多个接口
继承之后:方法的重写(override overwrite):
继承后,对父类同名方法的重写,覆盖
重写规则:
- 子类的“ 返回值类型 方法名(参数列表)”与父类相同。
- 子类方法修饰符不小于父类修饰符
- 若父类方法抛异常,则子类抛的异常类型不能大于父类
- 子父类方法必须同为static或同为非static的
- private 修饰的方法无法重写,只能重定义
- 继承之后:可使用super关键字(与this类似)类调用父类对象的:
- 修饰以调用父类的 属性,方法,构造器
- 属性:当子类与父类有同名属性时通过 super.父属性(类似this.子属性)调用父属性
- 方法:显式调用父类被重写的方法 super.method
- 构造器:在子类中使用super(形参列表)来显式调用父类中指定的构造器
声明在首行且只能有一句
当无声明this(…),super(…)默认调用父类空参 super()
- 修饰以调用父类的 属性,方法,构造器
3.3面向对象特性之三:多态性
多态体现在:
- 方法的重载与重写,这个在上面已经讲过。
- 类对象的多态性
通过父类的引用指向子类的对象实体,执行时为子类的重写方法(仅适用于方法)
/*
class Woman extends Person
继承之后+方法重写=子类对象的多态性
instanceof:判断p是否是Woman的一个实体
p既是Woman的实体,也是Woman父类(Person)的实体
p instanceof Woman:true
p instanceof Person:true
通过子类对象多态性,减少重载方法个数
如:public void eat(Person p){}
public void eat(Woman w){}
public void eat(Man m){}
可通过多态性减少为一个:public void eat(Person p){}
p,可为Person类及其子类
*/
Person p=new Woman();
//可通过强转回来:
if(p instanceof Woman){
Woman w=(Woman)p;
}
四,其他的关键字
static关键字:
说明:用来修饰类里面的东西,除了构造器,出现在对象前,消失在对象后
- 修饰属性:类变量,位于静态域中,被所有对象共有,其中一个对象进行更改,则被更改。
- 随着类的加载而加载,即在创建对象之前。且只有一份。
- 对象.类变量 类 .类变量 的方法调用
- 修饰方法:类方法,不依赖于对象
- 随着类的加载而加载,即在创建对象之前,且只有一份。
- 对象.类方法 类.类方法()的方式调用
- 方法中只能调用静态属性,或本类中静态的方法,不能显含或隐含this,super
final关键字:
- 修饰类,属性,方法
- 修饰类,表示类不能被继承,如String,StringBuffer,System
- 修饰方法,表示方法不能被重写,如Object类中的getClass()方法
- 修饰属性,表示属性为常量,初始化后不能被修改,常量通常大写,如Math.PI
此常量在哪赋值:
此常量不能使用默认初始化
可以显式赋值,以及代码块,构造器中赋值。 - 修饰引用数据类型,所指地址不能被更改
- static final 修饰,全局常量
abstract关键字:
- 修饰类:抽象类,不可被实例化,有构造器
- 修饰方法:抽象方法,没有方法体,如:public abstract void eat();
- 抽象方法所在类一定是抽象类
- 抽象类中可以没有抽象方法
this(当前对象的)关键字:
说明:修饰属性,方法,构造器,表示当前对象或当前正在创建的对象
- this.name;
- this.show();
- this(形参)调用指定重载构造器,放在首行,且只能有一句
- method(this):指代调用method 的对象