抽象类
概念:在继承的层次结构中,每个新子类都使类变得越来越明确和具体。如果从一个子类追溯到父类,类就会变得更通用,更加不明确。类的设计应该确保父类包含它的子类的共同特征。
一个类可以实现多个接口,但是只能继承一个父类
注意:抽象类不可以用于创建对象。
抽象类可以包含抽象方法,这些方法将在具体的子类中实现。 在函数中使用abstract修饰符表示()抽象类绝对不能创建对象
如果一个子类继承抽象类时,如果完全没有重写抽象函数,那么这个类也必须是抽象的(abstract)abstract void jiao(); } abstract class Dog extends Animal{ }
抽象类不一定有抽象函数;抽象类只能被子类调用
抽象类一定有构造函数(与一般类唯一不同的就是有构造函数)
抽象类不能与private,final ,static (与类无关,超凡脱俗),new关键字共存抽象类一般是作为父类存在的
接口(interface)
区别:接口是与类相似的一种结构,只包含常量和抽象方法
概念:接口的目的是指明这些对象是可比较的,可食用的,以及可克隆的
形式:
修饰符 interface 接口表{
/* 常量声明 /
/ 方法签名 */
}
类与接口之间的关系成为接口继承(接口继承和类继承本质上是相同的),简称继承
接口的由来:
如果一个抽象类中所有的方法都是抽象的,那么这个抽象类就可以用接口去表述,接口是一个特殊的抽象类
interface代替class【类和接口之间只能是实现关系】
接口内部的函数一律是 public abstract隐藏的默认的
接口内部的变量一律是 public static final
因此以下接口定义都是等价的:
接口:
- 为类添加功能
- 作为一种中间值传递(规范 规约)
注意:
类与接口之间的关系为多实现关系:给类多加功能
like a 关系
接口与接口之间多继承关系:只保留函数声明,并未指定具体执行,所以不会产生二义性
implements接口
与extends的区别:
extends是继承父类,只要那个类不是声明final或者定位为abstract(抽象类)就能继承,Java中不支持多重继承,继承只能继承一个类,但implements可以实现多个接口,用逗号分开即可。
class A extends B implements C,D,E(){}
在这其中:
class 是子类A的名称
extends 是父类B的名称
implements 是接口C,D,E的名称
与interface的区别:
interface是实现接口的关键字(定义接口时使用)
implement是代表接口的名词(使用接口时使用)
Comparable接口
—> Comparable接口定义了compareTo方法,用于比较对象
package java.lang;
public interface Comparable<E>{
public int compareTo(E o);
}
compareTo方法判断这个对象相对于给定对象o的顺序,并且当这个对象小于、等于或者大于给定对象o时,分别返回负整数、0或正整数。
Comparable 接口是一个泛型接口。在实现接口时,泛型类型E被替换成一种具体的类型。
compareTo方法来比较两个数字、两个字符串以及两个日期。
多态
—> 多态意味父类的变量可以指向子类对象
定义:继承关系使一个子类继承父类的特征,并且附加一些新特征。(多态是继承的前提)
父类的引用指向一个子类的对象
Fu f=new Zi();
instanceof关键字(判断其内部是否有相应结构体)
用法:a intanceof A 用来判断a对象是否A类的一个实例
返回值: boolean类型
注意:
要求a所属类和A必须是子类和父类之间的关系
如果a属于A类的子类B,也返回true
if(per instanceof Person){ //true
System.out.println("是person的一个实例");
}
if(per instanceof Object){ //
System.out.println("是Object的一个实例");
}
自己定义一个MyString类
/**
模拟String类自行设计一个MyString的字符串类
*/
public final class MyString implements Comparable<MyString>{
//作为MyString类的容器,用于存储字符
private final char[] value;
//默认创建长度为0的一个空串(MyString)
public MyString(){
this(new char[0]);
}
/**
外界传入一个字符数组用来创建MyString对象
*/
public MyString(char[] value){
this.value=value;
}
public char charAt(int index){
return value[index];
}
public MyString toUpperCase(){
char[] chs=copy();
for(int i=0;i<chs.length;i++){
char c=chs[i];
if(c>='a'&&c<='z'){
chs[i]=(char)(c-'a'+'A');
}
}
return new MyString(chs);
}
public MyString toLowerCase(){
char[] chs=copy();
for(int i=0;i<chs.length;i++){
char c=chs[i];
if(c>='A'&&c<='Z'){
chs[i]=(char)(c-'A'+'a');
}
}
return new MyString(chs);
}
private char[] copy(){
char[] chs=new char[value.length];
for(int i=0;i<value.length;i++){
chs[i]=value[i];
}
return chs;
}
public boolean contains(MyString ms){
char[] v1=value;
char[] v2=ms.value;
for(int i=0;i<v1.length;i++){
if(v1[i]==v2[0]){
if(i+v2.length-1<v1.length){
MyString s1=substring(i,i+v2.length);
if(s1.compareTo(ms)==0){
return true;
}
}else{
return false;
}
}
}
return false;
}
public MyString substring(int beginIndex){
return substring(beginIndex,value.length);
}
public MyString substring(int beginIndex,int endIndex){
char[] chs=new char[endIndex-beginIndex];
int index=0;
for(int i=beginIndex;i<endIndex;i++){
chs[index++]=value[i];
}
return new MyString(chs);
}
public boolean endsWith(MyString ms){
int beginIndex=value.length-ms.value.length;
return substring(beginIndex).compareTo(ms)==0;
}
public boolean startsWith(MyString ms){
return substring(0,ms.value.length).compareTo(ms)==0;
}
@Override
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(this==obj){
return true;
}
if(obj instanceof MyString){
MyString ms=(MyString)obj;
return this.compareTo(ms)==0;
}
return false;
}
/**
此方法从Comparable接口而来
对比MyStrnig对象之间的大小关系
@param ms 对比的目标
@return int整数
>0 当前对象比目标 大
==0 当前对象比目标 相等
<0 当前对象比目标 小
*/
@Override
public int compareTo(MyString ms){
int len1=value.length;
int len2=ms.value.length;
int min=Math.min(len1,len2);
char[] v1=value;
char[] v2=ms.value;
for(int i=0;i<min;i++){
if(v1[i]!=v2[i]){
return v1[i]-v2[i];
}
}
return len1-len2;
}
public int compareToIgnoreCase(MyString ms){
return this.toLowerCase().compareTo(ms.toLowerCase());
}
}
内部类
定义:在描述一个事物的时候,其中又存在着其他事物,则外面的事物叫做外部类,里面的事物叫做内部类
class InnerClassDemo{
public static void main(String[] args){
}
}
class Outter{
int num=10;
static int a=30;
public void show(){
System.out.println("Outter show");
}
class Inner{
int num=20;
int b=40;
public void show(){
System.out.println("Inner show"+num);
}
}
}
此时inner是outter的内部类
- 调用内部类中的其他成员:
Outter out=new Outter();
Outter.Inner in=out.new Inner();
或者 Outter.Inner in=new Outter().new Inner();- 内部类中无法直接创建静态成员,如需创建,需要将该类声明为静态。(因为静态优先于对象加载进静态方法区,该内部类的静态成员进入静态区时,只能在外部类已经创建对象结束,但此时静态已经加载完毕,无法达成优先,所以无法在内部类中直接创建静态成员)
内部类中如果出现静态,则其内部类也必须是静态。
static class Inner{
static int num=20;
int b=40;
public void show(){
System.out.println("Inner show"+num);
}
}
此时存在两个问题:
- 静态内部类中如何访问非静态成员:
创建类
Outter.Inner in = new Outter.Inner();
in.show();- 静态内部类中如何访问静态成员:
System.out.println(Outter.Inner.haha);
异常
定义:指非正常情况的错误
【异常体系的最终父类是Object】
函数内部的问题
- 函数自身内部解决
return 正常结果- 函数将问题反馈给调用者
throw 异常对象
数组角标越界
ArrayIndexOutofBoundsException
空指针异常
NullPointerException
栈溢出异常
StackOverFlowError
堆溢出异常
OutofHeapError
类型转化异常
ClassCastException
数字异常
ArithmeticException
数据转换异常
NUmberFormatException
抛出异常:JVM抛 throw 抛
Throwable
Error 严重性错误 JVM直接抛出内存错误 改代码
Exception 一般性错误 JVM可抛 throw抛
可以尝试改正(已经事先有解决方案)
RuntimeException 运行时异常
其他子类 编译时异常
自定义异常(继承Exception)
对于编译时异常
- 捕获 自身内部处理问题
- 声明 告诉调用者有问题
throw 异常类