面向对象

-本文仅为个人学习总结,方便个人复习,文章大部分内容为参考资料上的知识点。

面向对象与面向过程的区别

1、出发点的不同;
2、层次逻辑关系不同;
3、数据处理方式与控制程序方式不同;
4、分析设计与编码转换方式不同。

面向对象的特征

面向对象的主要特征包括抽象、继承、封装和多态。
1、抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象包括两个方面:一是过程抽象;二是数据抽象。
2、继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,他提供了一种明确的表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且派生类可以修改或增加新的方法使之更适合特殊的需要。
3、封装:封装是指将客观事物抽象成类,每个类对自身的数据和方法实行保护。类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
4、多态:多态是指允许不同类的对象对同一消息做出响应。多态包括参数化多态和包含多态。

面向对象开发方式的优点

1、较高的开发效率;
2、保证软件的鲁棒性;
3、保证软件的高可维护性。

继承

继承是面向对象中的一个非常重要的特性。通过继承,子类可以使用父类中的一些成员变量与方法,从而能够提高代码的复用性,提高开发效率。在Java语言中,被继承的类叫基类或父类,继承基类或父类的类叫派生类或子类(subclass)。继承是通过extends关键字来实现的,使用格式为:class子类名extends父类名。
继承主要有如下几下特性:
1、Java语言不支持多重继承,也就是说,子类至多只能有一个父类,但是可以通过实现多个接口来达到多重继承的目的;
2、子类只能继承父类的非私有(public与protected)成员变量与方法;
3、当子类中定义的成员变量和父类中定义的成员变量同名时,子类中的成员变量会覆盖父类的成员变量,而不会继承。
4、当子类中的方法与父类中的方法有相同的函数签名(相同的方法名,相同的参数个数与类型)时,子类将会覆盖父类的方法,而不会继承。

组合和继承区别

组合:指在新类里面创建原有类的对象,重复利用已有类的功能。
继承:面向对象的主要特性之一,它允许设计人员根据其他类的实现来定义一个类的实现。
组合和继承都允许在新的类中设置子对象,只是组合是显式的,继承是隐式的。组合和继承存在着对应关系:组合中的整体类和继承中的子类对应,组合中的局部类和继承中的父类对应。
继承代码如下:

class Verhicle{
}
class Car extends Verhicle{
}

组合代码如下:

class Tire{
}
class Car extends Verhicle{
private Tire t = new Tire();
}

继承和组合遵循以下两个原则:
1、除非两个类之前是“is-a”的关系,否则不要轻易地使用继承,不要单纯地为了实现代码的重用而使用继承,因为过多地使用继承会破坏代码的可维护性,当父类被修改时,会影响到所有继承自它的子类,从而增加程序的维护难度和成本;
2、不要仅仅为了实现多态而使用继承,如果类之间没有“is-a”的关系,可以通过实现接口与组合的方式来达到相同的目的。

多态的实现机制

多态是面向对象程序设计中代码重用的一个重要机制,他表示当同一个操作作用在不同对象时,会有不同的语义,从而产生不同的结果。
多态主要有以下两种表现形式:
1、方法的重载(overload):重载是指同一个类中有多个同名的方法,但这些方法有着不同的参数,因此在编译时就可以确定到底调用哪个方法,他是一种编译时多态。重载可以被看作一个类中的方法多态性。
2、方法的覆盖(override):子类可以覆盖父类的方法,因此同样的方法会在父类和子类中有着不同的表现形式。
示例:

 class  Base{
 public Base(){
 g();
 }
 public void f(){
 System.out.println("Base f()");
 }
 public void g(){
 System.out.println("Base g()");
 }
 }
 class Derived extends Base{
 public void f(){
 System.out.println("Derived f()");
 }
 public void g(){
 System.out.println("Derived g()");
 }
 }
 public class Test{
 public static void main (String[] args){
Base b = new Derived();
b.f();
b.g();
}
} 

程序的运行结果为:

Derived g();
Derived f();
Derived g();

在上述代码中,由于子类Derived的f()方法和个g()方法与父类Base的方法同名,因此Derived的方法会覆盖Base的方法。在执行Base b = new Derived()语句时,会调用Base类的构造函数,而在Base的构造函数中,执行了g()方法,由于Java语言的多态性,此时会调用子类Derived的g()方法,而非父类Base的g()方法,因此会输出Derived g()。由于实际创建的是Derived类的对象,后面的方法调用都会调用子类Derived的方法。

  • 编译时多态和运行时多态。编译时多态是通过方法的重载实现的,运行时多态是通过方法的覆盖(子类覆盖父类方法)实现的。

重载和覆盖的区别

  • 使用重载时要注意以下几点:
    1、重载是通过不同的方法参数来区分的,例如不同的参数个数、不同的参数类型或不同的参数顺序。
    2、不能通过方法的访问权限、返回值类型和抛出的异常类型来进行重载、
    3、对于继承来说,如果基类方法的访问权限为private,那么就不能再派生类对其重载;如果派生类也定义了一个同名的函数,这只是一个新的方法,不会达到重载的效果。
  • 使用覆盖时要注意以下几点:
    1、派生类中的覆盖方法必须要和基类中被覆盖的方法有相同的函数名和参数。
    2、派生类中的覆盖方法的返回值必须和基类中被覆盖方法的返回值想同。
    3、派生类中的覆盖方法所抛出的异常必须和基类(或是其子类)中被覆盖的方法所抛出的异常一致。
  • 重载和覆盖的区别主要有以下几个方面:
    1、覆盖是子类和父类之间的关系,是垂直关系;重载是同一个类中方法之间的关系,是水平关系。
    2、覆盖只能由一个方法或只能由一对方法产生关系;重载是多个方法之间的关系。
    3、覆盖要求参数列表相同;重载要求参数列表不同。
    4、覆盖关系中,调用方法体是根据对象的类型(对象对应存储空间类型)来决定;重载关系是根据调用时的实参表与形参表来选择方法体的。

接口与抽象类

接口和抽象类的相同点:
1、都不能被实例化;
2、接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能被实例化。
接口和抽象类的不同点:
1、接口需要实现(使用implements),但抽象类只能被继承(用extends)。一个类可以实现多个接口,但一个类只能继承一个抽象类,因此使用接口可以间接达成抽象类的目的;
2、接口强调特定功能的实现,其设计理念是“has-a”关系;而抽象类强调所属关系,其设计理念为“is-a”关系;
3、接口中定义的成员患变量默认为public static final,只能够有静态的不能被修改的数据成员,而且,必须给其赋初值,其所有成员都是public、abstract的,而且只能被这两个关键字修饰。而抽象类可以有自己的数据成员变量,也可以有非抽象的成员方法,而且,抽象类中的成员变量默认为default(本包可见),当然也可以被定义为private、protected和public,这些成员变量可以在子类中被重新定义,也可以被重新赋值,抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native等访问修饰符修饰,同时方法必须以分好结尾,并且不带花括号。所以,当功能需要积累时,用抽象类;不需要积累时,用接口。
4、接口被运用于实现比较常用的功能,便于日后维护或者添加删除方法;而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码进行修改。

this与super的区别

this:用来指向当前实例对象,它的一个非常重要的作用就是用来区分对象的成员变量与方法的形参(当一个方法的形参与成员变量的名字相同时,就会覆盖成员变量)。为了能够对this有一个更好的认识,首先创建一个类中的People,实例如下:

class People{
String name;
//正确的写法
}
public People (String name){
this.name = name;
}
public People (String name){
name = name;
}
}

上例中,第一个构造函数使用this.name来表示左边的值为成员变量,而不是这个构造函数的形式参数。对于第二个构造函数,由于在这个函数中形参与成员变量有着相同的名字,因此对于语句name=name,等号左边和右边的两个name都代表的是形式参数。在这种情况下,只有通过this才能访问到成员变量。
super可以用来访问父类的方法或成员变量。当子类的方法或成员变量与父类有相同名字时也会覆盖父类的方法或成员变量,要想访问父类的方法或成员变量只能通过super关键字来访问,示例如下:

class Base{
public void f(){
System.out.println("Base:f()");
}
}
class Sub extends Base{
public void f(){
System.out.println("Sub:f()");
}
public void subf(){
f();
}
public void basef(){
super.f();
}
}
public class Test{
public static void main (String[] args){
Sub s = new Sub();
a.subf();
s.basef();
}
}

程序运行结果为:

Sub:f()
Base: f()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值