🌈 个人主页:十二月的猫-CSDN博客
🔥 系列专栏: 🏀面向对象修炼手册💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光
目录
前言
行为
1 静态行为和动态行为
1.1 静态类和动态类
1.2 静态方法与动态方法
1.2.1 静态方法与动态方法区别
1.2.2 静态方法与动态方法的优缺点
1.2.3 静态方法与动态方法的方法绑定
1.3 静态类型与动态类型
多态
1. 重载、重写、重定义
1.1 重写(覆盖、改写、重置、覆写)
1.2 重载
1.2.1 重载解析
1.3 重定义
1.3.1 重定义解析
2 概念
3 特点
总结
前言
目前我们已经讨论了类以及对象,又进一步区分了对象和实例的区别。在此基础上,又研究了面向对象编程的思想——利用对象及消息机制解决问题、完成编程。
有了这样大框架作为基础,我们可以知道面向对象编程中最主要的东西就两个——1、对象;2、消息传递。消息传递的机制我们已经有了较为深入的研究(这一块并不复杂)。
接下来,我们要深入研究的是对象:包括对象的生成、对象的组织、对象的行为等
面向对象技术最主要的就是在研究对象的事情。
后面的设计模式和设计原则对应的就是对象的创建、组织和行为
既然是研究对象的事情,我们自然要先研究对象的三大性质——继承、多态、封装。只有我们深入理解了对象的三大性质才有后面的对象生成、组织与行为研究
行为
行为:在这里的含义就是具体的操作,研究行为就是研究面向对象中的一系列相同操作的集合(强调的是做法——如何做,并不强调这个行为是作用在哪个对象上)
另一种理解方式:
静态行为:静态化
动态行为:动态化
可以把这两个行为作用在不同对象上,产生不同类型的对象
例如:作用在类上形成静态类和动态类;作用在方法上形成静态方法和动态方法;作用在类型上形成静态类型和动态类型;作用在绑定方法上形成静态绑定方法、动态绑定方法
行为分为:静态行为和动态行为
1 静态行为和动态行为
1.1 静态类和动态类
变量的静态类是指用于声明变量的类。静态类在编译时就确定下来,并且再也不会改变(才class中就固定的,不再改变)
变量的动态类指与变量所表示的当前数值相关的类。动态类在程序的执行过程中,当对变量赋新值时可以改变。表示直到运行时绑定于对象的属性或特征(在main中可以由程序员自己设置,在运行时才确定类中的具体属性和特征)
1.2 静态方法与动态方法
1.2.1 静态方法与动态方法区别
- 静态方法在程序初始化后会一直贮存在内存中,不会被垃圾回收器回收
- 非静态方法只在该类初始化后贮存在内存中,当该类调用完毕后会被垃圾回收器收集释放(与类同生命周期)
- 静态方法在初始化类时初始化,并分配内存;动态方法只有先创建类的实例对象后,才能调用动态方法(静态方法属于类,动态方法属于具体的对象)
- 静态方法实在类装载的时候就加载的,可以直接用类名调用,不必实例化。动态方法,是在由具体的类的对象的时候由对象调用的(静态方法类和对象都可调用,动态方法只有对象调用)
- 静态方法在访问本类的成员时,只容许访问静态成员(即静态成员变量和静态方法),而不容许访问实例成员变量和实例方法;实例方法则无此限制(静态方法的限制)
1.2.2 静态方法与动态方法的优缺点
静态方法好处:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象都存一份。可以直接被类名调用
静态方法坏处:生命周期过长。访问出现局限性。(静态虽好,只能访问静态)
1.2.3 静态方法与动态方法的方法绑定
方法绑定含义:
绑定消息和响应消息的消息选择器(也就是响应消息的代码)
静态方法绑定:
静态绑定(前期绑定)是指:在程序运行前就已经知道这个消息的接收器是哪个,在编译的时候就可以连接到类的中,定位到这个方法。
在Java中,final、private、static修饰的方法以及构造函数都是静态绑定的,不需程序运行,不需具体的实例对象就可以知道这个方法的具体内容
理解:这个方法如果只有一份,不会重复也不会被修改,那么在编译时就可以直接绑定
动态方法绑定:
在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的
1.3 静态类型与动态类型
多态
多态的定义:当变量/方法的动态行为和静态行为不一致时,就出现了所谓的多态
1. 重载、重写、重定义
1.1 重写(覆盖、改写、重置、覆写)
定义:子类重写父类的方法
出现场景:父类和子类之间
特点:父类和子类方法名、参数、返回值类型都相同
方法绑定:根据调用这个方法的对象的类型来确定绑定哪个方法
多态:多态体现在完全相同的两个函数整体指代不同的代码实现
public class FatherOverride {
public void f() {
System.out.println("father f()");
}
public static void main(String[] args) {
FatherOverride o = new Derived();
o.f(); // 输出: derived f()
}
}
class Derived extends FatherOverride {
@Override
public void f() {
System.out.println("derived f()");
}
}
采用多态技术的优点:
引进多态技术之后,尽管子类的对象千差万别,但都可以采用 父类引用.方法名([参数]) 统一方式来调用,在程序运行时能根据子对象的不同得到不同的结果。这种“以不变应万变”的形式可以规范、简化程序设计,符合软件工程的“一个接口,多种方法”思想。
向上转型:子类本质是一种特殊的父类。当把一个子类对象赋值给一个父类引用变量时,子类对象会被自动向上转型,同时失去一些子类独有的方法 (在类的层次结构中,父类在上子类在下)
向上转型的例子:
class Animal {
public void speak() {
System.out.println("Animal speaks??");
}
}
class Dog extends Animal {
public void speak() {
bark();
}
public void bark() {
System.out.println("Dog barks!");
}
}
class Bird extends Animal {
public void speak() {
}
public void twitter() {
System.out.println("Bird twitters!");
}
}
输出:
向下转型:做出数值是否属于指定类的决定之后,通常下一步就是将这一数值的类型由父类转换为子类。这一过程称为向下造型,或者反多态,因为这一操作所产生的效果恰好与多态赋值的效果相反。
例子:
class Person {
public void fun1() {
System.out.println(“1.Person{fun1()}”); }
public void fun2() {
System.out.println(“2.Person{fun2()}”); }
}
class Student extends Person //继承了父类//Person,自然继承了方法fun1、fun2
public void fun1() { //覆写了父类中的方法fun1()
System.out.println(“3.Student{fun1()}”); }
public void fun3() {
System.out.println(“4.Student{fun3()}”); }
}
class TestJavaDemo2 {
public static void main(String[] args) {
Person p = new Person(); //父类对象由自身实例化
Student s = (Student)p; //将p对象向下转型
p.fun1();
p.fun2();} }
运行结果:
这里编译无错是因为:检查在编译时发生,范围和方式与静态绑定相同(根据变量类型)
运行出错是因为:发生动态绑定,运行时绑定实质对象(Person),但是运行时发现类型是Student
1.2 重载
定义:在同一个类定义中有多个同名的方法,但是方法的形参不同。调用时根据形参的不同调用不同的方法
出现场景:同一个类中
特点:同一个类中;方法名相同;方法形参不同
方法绑定:在编译时就绑定
多态:多态体现在同一个函数名能够指代多个过程
重载解析是在编译阶段执行
重写解析是在运行阶段执行
1.2.1 重载解析
重载解析就是指编译器在解析重载函数时的流程
方法如下:
重载解析小练习:
题目描述:
void order (Dessert d, Cake c);
void order (Pie p, Dessert d);
void order (ApplePie a, Cake c);
结果:
order (aDessert, aCake);//执行方法一
order (anApplePie , aDessert);//执行方法二
order (aDessert , aDessert);//错误
order (anApplePie , aChocolateCake);//执行方法三
order (aPie , aCake);//错误
order (aChocolateCake, anApplePie );//错误
order (aChocolateCake, aChocolateCake);//执行方法一
order (aPie , aChocolateCake);//错误
1.3 重定义
定义:在子类定义了一个和父类具有相同名称但是函数签名不同的方法时,发生重定义(父子类中函数名相同、签名也相同叫做重写;同一个类中函数名相同、签名不同叫做重载)
出现场景:父类和子类之间
特点:父子类;方法名相同;方法形参不同
多态:多态体现在同一个函数名能够指代多个过程
1.3.1 重定义解析
两种不同的技术解析重定义:融和模型和分级模型
融合模型
Java使用融合模型,对所有可能的方法进行检测,选择最匹配的方案
class Parent {
public void example (int a)
{System.out.println(“in parent method”);}
}
class Child extends Parent {
public void example (int a,int b)
{System.out.println(“in child method”);}
}
//main方法中:
Child aChild = new Child();
aChild.example(3);//用parent
aChild.example(3,4);//用child
解析技术的必要性:
重写后每一个函数只存在唯一的可能性——》不需要解析去选择
重载和重定义后每个函数可能存在多种选择——》需要解析技术去选择
2 概念
多态是面向对象程序设计(OOP)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态
多态是静态行为和动态行为下方法/变量类型不同时的体现
对于动态类型语言,所有的变量都可能是多态的。
对于静态类型语言,多态变量则是替换原则的具体表现。
可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准
3 特点
-
多态的前提1:是继承
-
多态的前提2:要有方法的重写
-
父类引用指向子类对象,如:Animal a = new Cat();
-
多态中,编译看左边,运行看右边
总结
本系列内容均来自:山东大学-潘丽老师-面向对象开发技术-课程ppt、《设计模式》、《大话设计模式》
如果觉得写的还不错,可以点个赞收藏一下呀~~
祝大家学业、事业、爱情顺利!
天天开心,没有Bug每一天