面向对象的定义
从现实世界中客观事物出发构建软件系统,并在系统的构造中尽可能运用人类的思维方式。
组成
类是用于描述同一个类对象的一个抽象概念,类通过属性和方法来对事物的静态属性和动态属性
面向对象的实例
类可以看成是一类对象的模板,对象可以看成一个类的具体实例。
车的定义,具有哪些特征才算是车,能载人(静态属性),能跑—前后左右(动态属性)车的外形,构造,比如,方向盘,车门,玻璃,车的颜色都是车的静态属性
总结:车有静态和动态的属性,在java中就有静态成员和动态成员(方法)去驱动这车,这就是把车给抽象开来,我们把车叫做类,书本也是一个类,电子产品也是一个类,我们把一类事物的具体某一个东西,符合这类事物特征的某个东西叫做对象。
eg.职员这个类该怎么抽象出来?也是从两个方面,一方面是它的静态属性,另一方面它的动态属性
职员有哪些属性呢?有姓名,年龄,目前工资数额等属性,
他有哪些方法呢?让这个职员来显示姓名,显示年龄,修改姓名,领取工资。当然显示姓名,显示年龄,修改姓名,领取工资这些也可以让别人来做,
但面向对象的设计思维是最合适的方法应该出现在最合适的类里面。显示姓名,显示年龄,修改姓名,领取工资由谁来做更合适呢,那就是职员自己最合适。
所以这些方法应该出现在职员这个类里面。
根据方法是没办法区分两个对象的。所以每个对象都有自己的属性,属性值和另外一个对象一般是不一样的
面向对象的三大特性
1.继承:xX is XX
定义
新定义的类是从已有的类中获取属性和方法的现象
特性
继承是单继承的
继承于覆盖难点
1
$ “继承的好处”
1.提高了代码的重用性
2.让类与类之间产生了关系,为多态创建条件
1
$ “注意事项”
当子类需要调用父类的构造方法的时候,需要注意
1)如果父类中无构造方法或者有一个无参的构造方法,子类也无构造方法,子类会显示地调用父类的构造方法
2)如果父类的构造方法有参构造,那么子类点用必须显式地调用有参的构造方法,要不然会报错
3)如果父类有无参和有参的构造方法,子类默认调用无参构造方法
方法覆盖:
1,子类覆盖父类地方法必须具有同样的参数返回类型
2,参数返回类可以是父类返回类的子类
3,子类只能把修饰符的作用域放大,而不能缩小
super关键字
super关键字和this的用法相同
this代表本类引用, super代表父类引用
当子类和父类出现同名成员的时候, 可以用super 和 this进行区分
例子:
/什么是继承/
public class ExtendsDemo1 {
public static void main(String[] args) {
Truck t = new Truck();
t.size = 100; //不建议这么写。初始化成员变量最好使用构造方法,或者提供set(), get()接口.
//货车类的一个实例t从汽车类从继承了size, color属性。
//而货车比汽车多一个货箱
}
}
class Car { //汽车
int size; //车体大小
String color; //颜色
}
class Truck extends Car { //货车
String packingBox; //货箱
}
多态
定义
指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
技术支持
动态绑定
多态的作用
消除类型之间的耦合关系
多态的必要条件
继承
重写
父类引用子类对象
优点
1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
运用
this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
class A {
public String show(D obj)…{
return (“A and D”);
}
public String show(A obj)…{
return (“A and A”);
}
}
class B extends A{
public String show(B obj)…{
return (“B and B”);
}
public String show(A obj)…{
return (“B and A”);
}
}
class C extends B…{}
class D extends B…{}
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.show(b)); ①
System.out.println(a1.show(c)); ②
System.out.println(a1.show(d)); ③
System.out.println(a2.show(b)); ④
System.out.println(a2.show(c)); ⑤
System.out.println(a2.show(d)); ⑥
System.out.println(b.show(b)); ⑦
System.out.println(b.show(c)); ⑧
System.out.println(b.show(d)); ⑨
分析:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法
,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
比如④,a2.show(b),a2是一个引用变量,类型为A,则this为a2,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到,
于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),
this仍然是a2,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,
但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为”B and A”。
封装
封装就是将属性私有化,提供公有的方法访问私有属性。
实现
.修改属性的可见性来限制对属性的访问
.并为每个属性创建一对取值(getter)方法和赋值(setter)方法
.用于对这些属性的访问
封装的必要性
通过封装,可以实现对属性的数据访问限制,同时增加了程序的可维护性。
由于取值方法和赋值方法隐藏了实现的变更,因此并不会影响读取或修改该属性的类,
避免了大规模的修改,程序的可维护性增强。
封装的优点
1、良好的封装能够减少耦合。
2、类内部的结构可以自由修改。
3、可以对成员进行更精确的控制
4、隐藏信息,实现细节。
例子
class Athlete {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
在toString()中直接用getName来获取私有的属性