新手提问:RUBY里有接口类或者抽象类继承接口的概念么

黑马程序员_Java学习笔记(四)_面向对象(下)抽象类和接口、内部类以及异常
黑马程序员_Java学习笔记(四)_面向对象(下)抽象类和接口、内部类以及异常
发布时间: 3:33:49
编辑:www.fx114.net
本篇文章主要介绍了"黑马程序员_Java学习笔记(四)_面向对象(下)抽象类和接口、内部类以及异常",主要涉及到黑马程序员_Java学习笔记(四)_面向对象(下)抽象类和接口、内部类以及异常方面的内容,对于黑马程序员_Java学习笔记(四)_面向对象(下)抽象类和接口、内部类以及异常感兴趣的同学可以参考一下。
---------------------- 、、期待与您交流! ----------------------
一、抽象类和接口
1、抽象类和抽象方法
抽象方法和抽象类都必须使用abstract修饰符来定义,有抽象方法的类必须被定义为抽象类,抽象类可以不含抽象方法。
抽象类和抽象方法的规则如下:
——抽象方法和抽象类都必须使用abstract修饰符来定义,抽象方法不能有方法体
——抽象类不能被实例化,无法使用new关键字调用抽象类的构造器创建抽象类的实例,即使这个抽象类不包含抽象方法。抽象类主要用于被子类调用。
——抽象类可以包含Field、方法、构造器、初始化块、内部类、枚举类6种成分。
——含抽象方法的类(包括直接定义一个抽象方法;继承一个抽象父类,但没有完全实现父类的抽象方法,以及实现一个接口,但没有完全实现接口所包含的抽象方法3种情况)只能被定义为抽象类。
1、 abstract不能修饰成员变量和局部变量,也不能修饰构造函数。
2、 abstract与final修饰符永远不能同时使用。原因很简单,前者修饰的类和方法要求被继承和重写,而后者修饰的类和方法要求不被继承和重写。
3、 abstract和static修饰符不能同时修饰一个方法。原因是,static修饰的方法可以通过类直接调用,当该方法被定义成抽象方法时,该类调用该方法时将出现错误(没有方法体)。
4、 abstract不能和private修饰符同时修饰一个方法。因为前者要求方法必须被重写,后者要求方法只属于该类。
2、抽象类的作用
抽象类体现的是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类大体上会保留抽象类的行为方式。
模板模式在面向对象设计中很常见,下面是使用模板模式的一些简单规则:
——抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象为抽象方法,留给子类实现。
——父类可能包含需要调用其他系列方法的方法,这些被调方法即可以有父类实现,也可以由其子类实现。父类提供方法只是定义了一个通用算法,其实现也许并不完全由自身实现,而必须依赖于其子类的辅助。
2、接口(interface)
&&&&&&&& 接口(interface)是更彻底的抽象类,接口里面所有方法都必须是抽象方法。接口的应用可以尽量降低软件系统各模块之间的耦合,为系统提供更好的可扩展性和可维护性。由于接口定义的是多个类共同的公共行为规范,这些行为是与外部交流的通道,因而接口里通常定义的都是一组公用方法。
1、接口的定义
定义接口要用到关键字interface,语法格式如下:
[修饰符] interface 接口名 extends 父接口1,父接口2……
零到多个常量定义……
零到多个抽象方法定义
1、 接口的命名规则和类相同。
2、 一个接口可以有多个直接父接口(类似于多继承),但接口不能继承类。
3、 由于接口定义的是一种规范,因此接口里不能包含构造函数和构造代码块。接口里的成员变量只能是常量,方法必须是抽象方法,可以有内部类(包括内部接口、枚举)。
4、 由于接口的定义,导致接口中成员变量和成员方法一般有固定修饰符:变量修饰符为:public static final;方法修饰符为:public abstract。即使在编程时没有指定,编译器也会自动添加以上修饰符。
2、接口的使用
类实现接口使用关键字implements,接口之间也可以继承,继承使用关键字extends,语法格式如下:
[修饰符] class 类名 extends 父类 implements接口1,接口2……
//以上语句实现了类继承父类的同时实现了接口1等多个接口。
1、 实现接口与继承父类相似,一样可以获得所实现接口里定义的常量Field、抽象方法、内部类和枚举定义。
2、 一个类可以同时继承父类并实现多个接口,但implements部分必须放在extends部分之后(如上面定义的语法格式)。
3、 实现类实现接口的方法权限修饰符必须是public。
3、接口和抽象类的比较
——都不能实例化,接口和抽象类都位于继承树顶端,用于被其他类继承
——都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法
1、 设计目的不同:
——接口定义的是一种规范,它制定了系统间各个模块应该遵循的标准,因此一个系统中的接口不应该经常改变;
——抽象类体现的是一种模板设计模式。它更像是系统实现过程中的中间产品:已经实现了系统的部分功能,但不能成为最终的产品,需要进一步完善,这种完善可以有多种不同的方式(多子类继承)。
2、 使用方法有差异:
——接口不能包含普通方法,抽象类可以。
——接口不能包含静态方法,抽象类可以。
——接口只能定义静态成员变量,抽象类既可以定义静态成员变量又可以定义普通成员变量。
——接口不能包含构造函数和构造代码块,抽象类可以。
—— 一个类最多只能有一个直接父类,包括抽象类;但一个类可以实现多个接口,这也弥补了Java单继承的不足。
二、内部类
将一个类定义在另一个类的内部,则形成所谓的内部类(也可叫嵌类),这个外面的类叫外部类(也可叫宿主类)。Java从JDK1.1开始引入内部类,主要有如下作用:
——提供了更好的封装,可以将内部类隐藏在外部类里面,不允许同一个包中的其他类访问。
——内部类成员可以直接访问外部类的私有数据(private修饰),但外部类不能访问内部类的实现细节。
——匿名内部类适合用于创建那些仅需使用一次的类。
1、非静态内部类
&&&&&&&& 一般情况下,内部类都被作为成员内部类定义,而不是作为局部内部类。成员内部类是一种与成员变量、,方法、构造函数等类似的类成员;局部内部类和匿名内部类则不是类成员。
&&&&&&&& 成员内部类分两种:静态内部类和非静态内部类。使用static修饰的成员内部类称为静态内部类,没有使用static修饰的成员内部类称为非静态内部类。
1、 非静态内部类可以直接访问外部类成员(包括private成员)。
2、 外部类不能直接访问非静态内部类的成员,如需访问,则应显示建立内部类对象。
3、 不允许在外部静态成员中直接使用非静态内部类(静态不能访问非静态)。
4、非静态内部类里不能有静态方法、静态成员变量、静态初始化快。
2、静态内部类
&&&&&&&& 如果使用static修饰一个内部类,则这个内部类就称为静态内部类。静态内部类属于外部类本身,而不属于外部类的某个实例对象。
1、 静态内部类只能访问外部类的静态成员
2、 静态内部类本身是外部类的一个静态成员,因此外部类的静态成员也可以使用静态内部类来定义变量、创建对象等。
3、 外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名或其实例对象作为调用者来访问。
4、Java允许在接口里定义内部类,默认使用public static修饰符,也即是说:接口内部类只能是静态内部类。
3、使用内部类
使用内部类主要有三种情况:
1、 在外部类内部使用内部类
&&&&&&& 此时使用方式与使用普通类没多大区别,唯一值得注意的是:不要在外部的静态成员中使用非静态内部类。
2、 在外部类以外使用非静态内部类
&&&&&&&&&& 如果希望在外部类以外的地方访问内部类(包括静态和非静态),则内部类不能使用private修饰符修饰,如果使用了其他修饰符(public、省略、protected),则只能有访问权限的类可以访问
&&&&&&&&&& 在外部类以外的地方定义内部类变量的语法格式为:
OuterClass.InnerClass varName
&&&&&&&&&& 因为非静态内部类的对象必须寄存在外部类的对象里,因此创建非静态内部类对象之前,必须先创建外部类对象。在外部类以外的地方创建内部类实例的语法格式为:
OuterInstace.new InnerConstructor()
3、 在外部类以外使用静态内部类
因为静态内部类是外部类类相关的,因此创建内部类对象时无须创建外部类对象。在外部类以外的地方创建静态内部类实例的语法格式为:
new OutClass.InnerConstructor()
不管是不是静态内部类,在外部类以外的地方定义内部类变量的方式都一样。
创建静态内部类的子类语法为:
[修饰符] class 类名 extends 外部类名.内部类名
4、局部内部类
&&&&&&&& 将一个类定义在方法里,则这个类称为局部内部类。局部内部类仅在方法里有效。由于局部内部类不能在外部类方法以外的地方使用,因此局部内部类也不能使用访问控制符和static修饰符修饰。
&&&&&&&& 如果需要使用局部内部类定义变量、创建对象或派生子类,都必须在局部内部类所在的方法内进行。
5、匿名内部类
匿名内部类适合创建那些只需要使用一次的类,创建匿名内部类时会立即创建一个该类的对象,这个类定义立即消失,匿名内部类不能重复使用。
定义匿名内部类的语法格式为:
new 父类构造函数(实参列表)| 实现接口()
//匿名内部类的类体部分
1、 匿名内部类必须继承一个父类或实现一个接口,且最多只能继承一个父类或实现一个接口。换句话说,匿名内部类其实是一个匿名子类对象。
2、 匿名内部类不能是抽象类,因为系统创建匿名内部类是会立即创建其对象。
3、 匿名内部类不能定义构造函数,因为其没有类名,无法调用构造函数。但可以定义构造代码块,通过构造代码块来完成初始化动作。
4、如果匿名内部类需要访问外部类的局部变量,则必须使用final修饰符莱修饰外部类的局部变量,否则程序报错。
三、处理对象
1、toString方法
&&&&&&&& toString()方法是Object类里的一个实例方法,因此所有Java类都有toString() 方法。不仅如此,所有Java对象都可以和字符串进行连接运算(+),此时,系统自动调用Java对象的toString方法的返回值和字符串进行连接运算。
&&&&&&&& Object类提供的toString方法返回值是该对象实现类的“类名+@+hashCode”值,一般情况下,这种描述方式并不能体现对象的真正有用信息,因此,用户需要重写toString方法。
2、== 和equals方法
&&&&&&&& ==和equals方法是Java判断两个变量是否相等的两种方式。
1、==运算符
&&&&&&&& 使用 == 运算符判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数值类型(不要求数据类型严格相同),则只要两个变量的值相等,就返回true。
&&&&&&&& 如果两个变量是引用形变量,则必须是它们指向同一个对象时,== 才返回true。== 不可用于比较类型上没有父子关系的两个对象。
2、equals方法
&&&&&&&& equals方法是Object类提供的一个实例方法,因此所有引用变量都可以调用该方法来判断是否与其他引用变量相等。但使用这个方法的判断标准与 == 运算符没有区别,因此在实际开发中,一般需通过重写该方法来自定义来两个引用型变量相等的标准。重写equals方法需遵循如下规范:
自反性:对于任何非空引用值&x,x.equals(x)&都应返回&true。 对称性:对于任何非空引用值&x&和&y,当且仅当&y.equals(x)&返回&true&时,x.equals(y)&才应返回&true。传递性:对于任何非空引用值&x、y&和&z,如果&x.equals(y)&返回&true,并且&y.equals(z)&返回&true,那么&x.equals(z)&应返回&true。一致性:对于任何非空引用值&x&和&y,多次调用&x.equals(y)&始终返回&true&或始终返回&false,前提是对象上&equals&比较中所用的信息没有被修改。对于任何非空引用值&x,x.equals(null)&都应返回&false。
Tips:当此方法被重写时,通常有必要重写&hashCode&方法,以维护&hashCode&方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
1、异常概述
&&&&&&&& 目前主流的编程语言如Java、C#、Ruby、Python等都提供了成熟的异常机制。异常机制可以使程序中的异常处理代码和正常业务代码分离,保证程序代码更加优雅,并可以提高程序的健壮性。
&&&&&&&& Java把所有非正常情况分成两种:异常(Exception)和错误(Error),它们都继承自Throwable父类。Error错误,一般指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等,这种问题无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误。
&&&&&&&& Java中异常体系中的所有类及类所建立的对象都具备可抛性,可以被throw和throws操作。
2、异常处理
1、使用try…catch捕获异常
Java中异常处理机制的语法结构为:
//业务代码
catch (Exception e){
//异常处理代码
//必须执行的代码
1、 try…catch结构中的finally块里面的代码即使是程序遇到了异常,不能继续执行,也会先执行完finally块里面的代码再结束,因此,finally块里面的代码一般是用来释放系统资源。没有调用系统资源时,也可以不添加finally块。(如果catch块里有:System.exit(0)语句,则不会执行到finally块,因为直接退出虚拟机了。)
2、 如果遇到在方法内不能处理的异常时,可以在catch块里用throw关键字再将异常抛出给调用者。也可以先对异常进行初步处理,然后再throw新的异常给调用者。
3、 如果方法里出现了异常但并未处理,直接用throw关键字抛出了异常。此时,需要在方法上声明可能会出现的异常(RuntimeException除外)。语法格式为:在方法名后面写上:throws 异常1,异常2……
2、多异常捕获
Java7之前,捕获多异常需使用多个catch块,每个catch块只能捕获一种异常。Java7开始,实现了一个catch块可以捕获多个异常。使用一个catch块捕获多种类型的异常时需要注意如下两个地方:
——多种异常类型之间用竖线(|)隔开。
——异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值。
3、覆盖时的异常特点
——子类在覆盖父类时,如果父类的方法抛出异常,那么子类的方法只能抛出父类异常或异常的子类。
——如果父类方法抛出多个异常,子类覆盖只能抛出父类异常的子集。
——如果父类或者接口的方法中没有抛出异常,那么子类不能抛出异常
——如果用多个catch块处理多个异常,需将处理父类异常的catch块放在最下面
3、自定义异常
&&&&&&&& 实际开发中,往往针对特定项目需要定义特定异常,以便于提高程序可读性。自定义异常需要继承Exception或其子类。这样做有三个个好处:
——可以将指定问题进行封装,方便处理
——让自定义异常具备可抛性
——让自定义异常具备操作异常的共性方法
Java中异常对象都包含以下几个常用方法:
——getMessage():返回该异常的详细描述字符串。
——printStackTrace():将该异常的跟踪栈信息输出到标准错误输出。
——printStackTrace(PrintStreams):将该异常的跟踪栈信息输出到指定输出流。
——getStackTrace():返回该异常的跟踪栈信息。
&&&&&&&& 如果在自定义异常时,需要自行定义异常的详细描述,即可将信息以字符串的形式传递给父类的构造函数。例:
class MyException extends Exception
MyException (String message)
super(message);
4、RuntimeException
Java中异常可以分为两种:编译时异常和运行时异常。编译时异常是编译器可以检查出来的,如果不处理,则会编译失败;而运行时异常即RuntimeException,在编译时是检查不到的,到运行时才会发现异常,一般来说,发生该异常时建议不要处理,让程序停止,需要检查代码。
&&&&&&&& Runtime异常无需显式声明抛出,如果程序需要捕获Runtime异常,也可以使用try…catch块来实现。
5、throw和throws的区别
——使用位置不同:throw在方法内抛出,throws在方法上(方法名后定义)抛出。
——抛出内容不同:throw抛出的是异常实例,throws抛出的是异常类。
——抛出数量不同:throw一次只能抛出一个异常对象,throws可一次抛出多个异常类,中间用逗号隔开。
——throw表示已经出现异常,throws仅表示可能出现异常,实际运行程序有可能未发生异常。
——throw不能单独使用,出现throw语句,要么使用try…catch处理异常,要么在方法头上使用throws声明异常;throws可单独使用,仅在方法上声明异常,而不在方法内处理(让调用者处理)。
---------------------- 、、期待与您交流! ----------------------
本文标题:
本页链接:本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 抽象类继承接口 的文章

 

随机推荐