转至:http://sllereak.blog.163.com/blog
--面向对象和面向过程
* 面向过程: 手把手的教他;了解所有的业务流程。
* 面向对象: 告诉他去干什么事,别的不用操心;因为他自己了解自己的内部结构;
* 所以面向过程的编程是考虑是怎样一步一步的做 ,而面向对象的编程首先考虑的是应该有哪些对象,以及对象之间的关系,比如关联,继承,聚合,多态,实现等等
* 面向对象在分析问题,设计方案方面的作用也是很大的,比如jof的23中设计模式,也是基于面向对象,大量运用了继承,封装,多态的特性来支持设计原则,从而提高了代码重用和扩展。
因为程序设计始终是按照这样的方向发展的,重用,扩展,维护,而面向对象更容易实现这样的要求,并且从人对事物的认识方面,面向对象的设计更加符合人的思维,也就是更加容易掌握
* 但是呢面向过程一直存在于对象的行为中,需要根据特定的领域需求来选择
* 比如一些简单的方法调用,调用一个静态方法总会比new出来一个对象好,比如MATH类,还有就是单例设计模式和静态类完全就抛弃了面向对象的思想。
结论是这两种思想是相辅相成的
--类和对象
类是具有共同特征的一类事物的抽象,类中定义了这一类事物所共同持有的属性和方法。
对象是某一个类型的具体实例,类可以看成对象的一个模版。而对象就是依照这个模版生产出来的产品
--类与类之间的关系
*关联:一个类要用到另一个类
*继承:什么是一种什么
*聚合(聚集和组合的简称):什么是什么的一部分
聚合又分成两类
*聚集:单个和整体没关联,比如一个寝室由四个人聚集而成,每一个人都不是这个寝室寝室必不可少的部分,因为可以换寝室啊
*组合:单个和整体有依赖关系,比如一个人有头和身体组合而成,头是人必不可少的部分
当然如果需要细分的话还有实现,多态这些关系
--为什么使用面向对象
*程序设计始终是按照以下这几方面发展的
可重用性
可扩展性
维护更加方便
而面向对象的编程模式在基于以前的面向机器和面向过程比较之下更容易达到以上的需求
这是从程序的设计方面来考虑,从人对事物的认识方面,面向对象的设计更加符合人的思维,也就是更加容易掌握
--在内存中区分类和对象
*类是静态的,位于内存中的code segment区域中
*对象的引用地址位于栈中,所指向的实例位于堆中
类的静态成员只有一份,加载类的时候就被加载并且初始化(类加载是在第一次使用类的时候)
静态变量是存放在data segment(所有的静态变量和常量都是放在data segment中的),所有的方法(实例和静态方法存放在code segment)
每一个对象的方法只有一份,当调用的时候才分配内存(方法也是存在于code segment内存区域中,以一段静态代码保存)
--方法的重载
*唯一要求返回值和方法名一样,但是参数列表不一样就能构成重载
*void max(int x,int y)和void max(short x,short y)是构成重载的,只不过调用的时候需要注意你传进去的什么类型而已
--java中除了java.lang是自动import的,不需要手动导入的。其他的都需要手动导入
--访问修饰符
类本身 同一个包中 子类 任何
private 可以 不能 不能 不能
default 可以 可以 不能 不能
protected 可以 可以 可以 不能
public 可以 可以 可以 可以
其中default表示包中可以访问
普通类上只能有default和public两种修饰符(但是内部类是可以使用private和protected修饰符的)
--继承
是为了实现代码重用,体现类与类之间父子关系的面相对象设计的一套机制
*子类继承父类的所有成员包含静态成员(包括私有成员,只不过只有拥有权而没有使用权)
*方法的重写,子类的方法的访问控制符不能严格于父类的,要不然怎么实现多态呢?
*方法的重写,子类的方法的访问控制符可以大于或者等于父类的访问修饰符
*实例成员是被继承的,但是如果子类和父类的成员名称一样的话(访问修饰符随意取),那么各自是各自的成员(this就会指向子类的同名成员)
*可以将重写的规则运用到静态方法中,静态方法可以继承,可符合方法重写的规则,单不实现多态
*静态成员也是能被继承下来的,和实例成员完全一致
--
*一个子类中之所以能用super调用父类的成员,那是因为子类的内存中有父类的对象实例
*既然父类对象是存在的那么肯定会调用父类的构造方法。这也就是为什么实例化子类对象的时候会先调用父类的构造方法再调用子类的构造方法(默认调用父类的无参构造函数,但是如果用super显示调用父类的任意一个构造函数都不会再自动的调用无参的构造函数)
*注意如果使用super()调用父类的构造函数,则这条语句必须位于第一句,这也符合逻辑!但是还是需要理解和注意
--String,Date重写了equals方法,只要两个String的值相同就返回true,Object中是和"=="相同的 (注意"=="作用在引用类型的时候永远是比较引用地址,然而C#在比较String的时候重载了这个运算符号的) 注:java中不是很注重操作符的重载
--注意这个运算符 obj instanceof Cat 判断obj所“指向的对象”是否属于Cat或者Cat的子类,这里的obj“所指向的对象”是在堆中实际的类型
比如Object o=new Cat(); o的引用类型是Cat所以 o是Cat类型
结论:只要obj instanceof Cat为true那么obj就可以强制转为Cat对象,否则就会出现转换异常
--指针下移不会修改指针的值(非常重要哦)
--多态--也叫动态绑定--晚绑定
*多态是指在运行期间(而不是在编译期间)判断所引用对象的实际类型,根据实际类型调用具体的方法
*多态是面向对象的最核心机制
*当一个父类指针指向子类的引用,如果该子类重写了父类的某个方法,在运行时调用父类的该方法时候,该父类指向code segment中的方法指针会动态的改变,指向实际引用类型的方法
*由于有了多态的机制,也就是这种晚绑定的特征,才使得面向对象编程具有强大的扩展性,因为客户程序只需要持有同一类型的引用就能在运行时根据不同的情况完成不同的事情,很好的实现了对扩展开放,对修改封闭,还有面向抽象编程这样几个最基本的设计原则。
*随后的大多数面向对象的设计模式都是在这一机制的基础上进行扩展,来应对各种情况,各种需求,而终止达到最优的设计
*创建型,结构型,行为型,里面基本上都有多态的影子在里面
--final关键字
*final的变量不能被修改
成员变量可以声明成final
局部变量(常用在形式参数,当然代码块中的变量也可以是final的)可以声明成final,表示如果实参一旦传递给它,那么在方法里面是不允许改变的
*final的方法不能被重写(当然抽象方法不能使用final)
*final的类不能被继承(当然抽象类是不可能使用final的,尝试去理解编译器开发者设计原则)
*静态的final成员变量可以再申明的时候初始化,也可以在静态块中初始化
*实例final成员变量可以再申明的时候初始化,也可以在构造函数中初始化(但是必须保证在构造完成对象的时候初始化成功)
--抽象类和接口
*抽象类就是一个残缺不全的类,它其中提供的未实现的方法叫抽象方法,(所以他不能直接实例化)它的存在意义在于它强制要求子类重写它的抽象方法,从而实现多态
*接口是一种特殊的抽象类,这种抽象类只能包含常量和方法的定义,而没有变量(虽然你写出来像成员变量,但是编译器最终自动加上public static final),也没有方法的实现,也不能有构造方法
*接口的修饰符不自动加上public也就是说如果没有加上这个修饰符,在其他包下面是无法访问该接口的
*但是(如果在没有写全的情况之下)接口中的常量自动为public staitc final,接口中的方法自动为public abstract
*注意一点很重要的问题,接口中不允许使用静态块,所以里面的常量在申明的时候就必须要给初始值
*从设计层面上讲:当注重什么是一种什么的时候使用抽象类,当注重什么能做什么的时候使用接口
*还有就是一个类可以实现多个接口,但是不能继承自多个抽象类
//强调一下下面的问题
*interface A{
void fun1();
}
interface B{
void fun2();
}
class C implements A,B{
public void fun1(){}
public void fun2(){}
}
class App{
A a=new C();
B b=(B)a;
//这是允许的,因为a中实际的类型就是C
//秘籍:强制类型转化的是实际在堆上的内存的类型,理解这个了就理解了一切
}
*java中不支持显示接口的实现模式
比如
-----------------------------
interface A{
void fun();
}
interface B{
void fun();
}
class C implements A,B{
public void fun(){}//这是可以的两个接口的方法都能实现(两个都实现了撒)
}
但是
-----------------------------
interface A{
int fun();
}
interface B{
void fun();
}
class C implements A,B{
public void fun(){}
public int fun(){
return 1;
}
//这显然是不能通过编译的,再次只能希望sun的下一个JDK版本能实现现实接口实现的模式^_^
这一点没人家微软来的仔细
}
--接口和抽象类的区别文字描述
*接口就是一种特殊的抽象类,接口里面只能有静态常量和抽象方法,不能有方法实现,成员变量,也不能有静态块,和构造函数,而抽象类没有限制
*从设计上比较,接口注重的是一个类能做什么,而抽象类注重的是一个类是一种什么
*一个类可以实现多个接口,但是不能继承自多个抽象类
*相同点是他们的初衷都在于又提供给子类来重写它所申明的抽象的方法,从而实现多态