面向对象
面向过程
面向过程就是一步一步来的,适合处理简单问题
面向对象
面向对象编程(Object Oriented Programming)OOP的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
对象的含义是指具体的某一个事物,即在现实生活中能够看得见摸得着的事物。在面向对象程序设计中,对象所指的是计算机系统中的某一个成分。在面向对象程序设计中,对象包含两个含义,其中一个是数据,另外一个是动作。对象则是数据和动作的结合体。对象不仅能够进行操作,同时还能够及时记录下操作结果。
方法是指对象能够进行的操作,方法同时还有另外一个名称,叫做函数。方法是类中的定义函数,其具体的作用就是对对象进行描述操作。
继承简单地说就是一种层次模型,这种层次模型能够被重用。层次结构的上层具有通用性,但是下层结构则具有特殊性。在继承的过程中类则可以从最顶层的部分继承一些方法和变量。类除了可以继承以外同时还能够进行修改或者添加。通过这样的方式能够有效提高工作效率。在这里举一个例子,当类X继承了类Y后,此时的类X则是一个派生类,而类Y属于一个基类。 继承是从一般演绎到特殊的过程,可以减少知识表示的冗余内容,知识库的维护和修正都非常方便。更有利于衍生复杂的系统。
类是具有相同特性(数据元素)和行为(功能)的对象的抽象。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。
类映射的每一个对象都具有这些数据和操作方法,类的继承具有层次性和结构性,高层次对象封装复杂行为,具体细节对该层次知识保持透明,可以减小问题求解的复杂度。
封装是将数据和代码捆绑到一起,对象的某些数据和代码可以是私有的,不能被外界访问,以此实现对数据和代码不同级别的访问权限。防止了程序相互依赖性而带来的变动影响,面向对象的封装比传统语言的封装更为清晰、更为有力。有效实现了两个目标:对数据和行为的包装和信息隐藏。
多态是指不同事物具有不同表现形式的能力。多态机制使具有不同内部结构的对象可以共享相同的外部接口,通过这种方式减少代码的复杂度。一个接口,多种方式。
动态绑定指的是将一个过程调用与相应代码链接起来的行为。动态绑定是指与给定的过程调用相关联的代码只有在运行期才可知的一种绑定,它是多态实现的具体形式。
消息传递:对象之间需要相互沟通,沟通的途径就是对象之间收发信息。消息内容包括接收消息的对象的标识,需要调用的函数的标识,以及必要的信息。消息传递的概念使得对现实世界的描述更容易。
面向对象的方法就是利用抽象、封装等机制,借助于对象、类、继承、消息传递等概念进行软件系统构造的软件开发方法。
特征
-
对象唯一性。
每个对象都有自身唯一的标识,通过这种标识,可找到相应的对象。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。 -
抽象性(封装)。
抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。 -
继承性。
继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
继承性是面向对象程序设计语言不同于其它语言的最重要的特点,是其他语言所没有的。
在类层次中,子类只继承一个父类的数据结构和方法,则称为单重继承。
在类层次中,子类继承了多个父类的数据结构和方法,则称为多重继承。
多重继承,JAVA、VB、NET、Objective-C均仅支持单继承,注意在C++多重继承时,需小心二义性。
在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,它简化了对象、类的创建工作量,增加了代码的可重用性。
采用继承性,提供了类的规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性。 -
多态性(多形性)
多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
多态性允许每个对象以适合自身的方式去响应共同的消息。
多态性增强了软件的灵活性和重用性。 [2]
基本思想
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一个事物在整个解决问题的步骤中的行为。面向对象程序设计中的概念主要包括:对象、类、数据抽象、继承、动态绑定、数据封装、多态性、消息传递。通过这些概念面向对象的思想得到了具体的体现。
传统的结构化设计方法的基本点是面向过程,系统被分解成若干个过程。而面向对象的方法是采用构造模型的观点,在系统的开发过程中,各个步骤的共同的目标是建造一个问题域的模型。在面向对象的设计中,初始元素是对象,然后将具有共同特征的对象归纳成类,组织类之间的等级关系,构造类库。在应用时,在类库中选择相应的类。
面对对象程序设计是尽可能地在模拟人类的思维。通过这样的方式能够让开发的软件更加符合人类的认知,人们使用起来也能够更加顺手。并且通过应用软件能够切实地解决现实生活中的问题。面向对象程序设计使得描述问题的问题空间和问题的解决方法空间组合在一起,并且尽可能地保持一致。能够将客观世界中的抽象问题转化为具体的问题对象。
面向对象的思维更符合人认识和思考问题的方式,面向对象的概念和应用已经超越了软件开发和程序设计,扩展到多个的领域,其中一个应用的分支就是面向对象的知识表示法。这种表示法把组成客观世界的实体抽象为数据和对数据的操作,并使用类把数据和对数据的操作封装成为一个不可分割、互相依存的整体。面向对象表示的知识更接近客观世界,表示方案更加自然,易于理解。面向对象技术良好的模块性,面向对象的系统良好的可维护性、可扩充性和可重用性等特点,正符合人们组织和管理知识库的需求。
对于描述复杂的事物,为了从宏观上把握、整体上合理分析,我们要用面向对象的思路来分析整个系统。但是具体到围观操作,人需要面向过程的思路去处理。
回顾方法
/*
修饰符 返回值类型 方法名(...){
//方法体
return 返回值;
}
*/
方法的定义
- 修饰符
- 返回类型
- break:跳出switch,结束循环和return的区别
- 方法名:注意命名规范就好
- 参数列表(参数类型,参数名)
- 异常抛出
方法的调用:递归
- 静态方法
- 非静态方法(必须要实例化后才能调用)
- 形参和实参
- 值传递和引用传递
- this关键字
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
对象是抽象概念的具体实例
对象的创建与初始化
使用new关键字创建对象
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象,进行默认的初始化以及对类中构造器的调用。
构造器
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点。
- 必须和类名相同
- 必须没有返回类型也不能写void
内存分析就暂时不做
总结类与对象
- 类与对象
类是一个模板:抽象,对象是一个具体的实例 - 方法
定义、调用! - 对应的引用
引用类型:基本类型(8)
4大类
整形:byte,short,int,long
浮点:float,double
字符:char
布尔:boolean
对象是通过引用来操作的:栈—>堆 - 属性:字段field 成员变量
默认初始化:
数字:0 0.0
char:u0000
boolean:false
引用:null
但是必须有一个初始值,否则会报错
修饰符 属性类型 属性名 = 属性值!
public static void main(String[] args) {
char c;
System.out.println(c);
boolean b;
System.out.println(b);
int i;
System.out.println(i);
int in[];
System.out.println(in);
String s;
System.out.println(s);
}
- 方法的定义和调用
- 对象的创建和使用
- 必须使用new 关键字创建对象,new关键字,对象的属性,对象的方法
- 类:静态的属性-属性,动态的行为-方法
- 封装,继承,多态
面向对象三大特性
封装
比如说数据库内的id字段就不应该给用户展示出来。
该露的露,该藏的藏
我们设计程序要追求高内聚,低耦合。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合仅暴露少量的方法给外部使用。
封装(数据的隐藏)
通常,应该禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
基本逻辑是,属性私有,用get/set方法来访问和改变数据内容。
继承
继承的本质是对某一批类的抽象,从而实现更好的建模
extends的意思是扩展,子类是父类的扩展
java中类只有单继承
继承是类和类之间的一种关系。除此之外,类和类之间还有依赖、组合、聚合等
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
子类和父类直接,从意义上讲应该有 is a 的关系
public 可以继承
private 不能继承
protected 同包内继承
default 也是public
object是一切类的父类,所有类都直接或间接继承object类
super可以调用父类的方法:区别this与super
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或构造方法中
- super金额this不能同时调用构造方法
this注意点
-
this代表当前这个对象
-
super代表父类对象的应用
-
this没有继承也能用
-
super只能继承的条件下使用
-
this()本类的构造
-
super()父类的构造
方法重写,覆盖父类的方法
类A
public class A {
public static void test(){
System.out.println("A->test");
}
}
类B继承类A,重写test();
public class B extends A{
public static void test(){
System.out.println("B->test");
}
}
main
public class hello {
public static void main(String[] args) {
B b = new B();
b.test();
A a = new B();
a.test();
}
}
输出
B->test
A->test
这里就是父类引用指向了子类
也就是向上转型
如果这里将static去掉
将会是完全一样的
B->test
B->test
总结一下,加了static的静态方法和等号左边有关,否则和右边有关。
特别注意
静态方法是类的方法,非静态方法是对象的方法。
a是new B出来的,因此调用了a的方法。
非静态就是重写,可以加上@override注解
重写:需要有继承关系,子类重写父类的方法!
- 方法必须相同
- 参数列表需要相同
- 修饰符:范围可以扩大但是不能缩小:public>protected>default>private
- 抛出的异常:范围,可以被缩小,但是不能扩大:ClassNotFoundException --> Exception(大)
多态
动态编译:类型可扩展
同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多
B b = new B();
A a = new B();
Object c = new B();
//一个对象的实际类型是确定的
//可以指向的引用类型就可以是父类
多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
如果子类重写了父类的方法,就执行子类的方法。
父类只能执行父类有的方法,不能获得子类独有的方法。
Object a = new B();
a.test();
上面这个列子会报错。
但是
B b = new B();
Object a = new B();
((B)a).test();
强制转换过来后就可以正常使用
注意:
- 多态是方法的多态,属性没有多态性
- 父类和子类,有联系的,否则会有ClassCastExceptionn
- 存在条件:继承关系,方法需要重写,父类引用指向子类对象!
不行
4. static方法,属于类,不属于实例,不能动
5. final 常量
6. private 方法
instanceof
instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。
- obj 必须为引用类型,不能是基本类型
- 在 JavaSE规范 中对 instanceof 运算符的规定就是:如果 obj 为 null,那么将返回 false。
- obj 为 class 类的实例对象
- obj 为 class 接口的实现类
- obj 为 class 类的直接或 间接子类
如果 obj 不为 null 并且 (T) obj 不抛 ClassCastException 异常则该表达式值为 true ,否则值为 false 。
父类转换为子类:
- 把子类转换为父类,向上转型
- 把父类转换为子类,向下转型,强制转换就有可能丢失方法。
static详解
静态代码块
static{
System.out.println("静态代码块");
}
static只执行一次
匿名代码块
{
System.out.println("匿名代码块");
}
每次都要来执行,和对象同时产生,先于构造器
静态导入包
import static java.lang.Math.random;
这样后就不用Math.random();直接用random();就好了
抽象类
public abstract class action{//抽象类
public abstract void doSomething(){}//抽象方法
}
抽象类的所有方法,继承了它的子类,必须要实现它的方法。
不能直接new这个抽象类,只能靠子类去实现它:约束
抽象方法必须在抽象类中
抽象类中给可以写普通方法
抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super()或super(参数列表)调用抽象类中的构造方法。
接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有!
- 接口:只有规范,约束和实现分离
关键字就是interface
接口中默认的就是public abstract前缀
public interface C {
void cFunction();
}
接口的实现
关键字implements
public class D implements C{
@Override
public void cFunction() {
}
}
可以利用接口实现多继承
public class D implements C ,Cpuls{
@Override
public void cFunction() {
}
}
接口中的常量是
public static final的默认前缀,但是一般不用
内部类
内部类就是在一个类中定义另一个类,可以获得外部类的私有属性,私有方法。
public class A {
private int a=0;//外部属性
public class Inner{
public void geta(){
return a;
}
}
}
内部类有
- 成员内部类
可以获得外部类的私有属性,私有方法。 - 静态内部类
加上static,和一般的static的性质一样 - 局部内部类
public class A {
public void method(){
class Inner{}//
}
}
- 匿名内部类
没有名字初始化类,不用将实例保存到变量中
public class hello {
public static void main(String[] args) {
new B().test();//匿名类
}
}
或者
public class hello {
public static void main(String[] args) {
B b = new B(){
public void hello(){}
};
}
}
重点
一个java类中有多个class类,但是只能有一个public class类
public class A {
}
class Inner{
public void in(){}
}