成为Java程序员Day8:继承,多态,接口,抽象类.....

继承

创建分等级层次的类
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
Java中只有单继承

父类和子类的关系不像现实生活中的父子关系,更像师徒关系。就是师父会的,徒弟都会,徒弟下山后学的,师父不会,而且徒弟可以对师父的功夫加以改造,更适合自己。

当我们创建子类对象时,他会先开辟一片父类对象的空间。并且给子类添加一个super变量储存父类的地址。
子类.方法名() 使用时,会先在子类中找,没有再到父类中找。

Super关键字

访问父类构造方法
-----调用父类的构造方法,必须把调用父类构造方法语句放在子类构造方法的第一句。
Super();//调用父类构造方法
访问父类属性
访问父类方法

重写(override)

1 参数列表必须完全和被重写的方法相同
2 返回类型必须和被重写的方法相同
3 访问权不能比父类重写的访问权限更低 例:父类为public 你不能声明为protected
4 父类成员方法只能被他的子类重写
5 声明为static和private的方法不能重写,但是能够被再次声明( static和private没有被继承到, static和 private 是被继承了,但是没办法重写,可以自己声明)

老师说:继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。private修饰的属性或方法,父类中的私有信息,子类不能访问到,及时想访问,也不是直接访问,而是通过封装方法,这种叫访问,不能叫继承。

额外收获

@Text
这个注解
1:首bai先需要导入import org.junit.test这个jar包,@Test注解要写在你要测试的方法上面
2:然后点击–运行方式,再点击Junit测试,dao就可以了。
test()方法里面写你需要测试的方法就可以了
—我对test的理解是TestMethods这个类不用new,就可以运行。是因为它是通过org.junit.Test中的API中的类反射生成的,然后调用用@Test注解的方法,有几个@Test注解,就运行几个test方法。

@是注bai解
@Test注解是JUnit测试的基础,它提供du了其他作用
1.指定将会抛zhi出的异常类型,如dao果没有抛出异常或者抛出的一场不属于我们指定的类型,就会算是测试失败了。
@Test(expected = RuntimeException.class)

2.测试一断代码运行时间
@Test(timeout=100)

final关键字

final用于修饰属性、变量
-----变量成为了常量,无法二次进行赋值。
final修饰的局部变量,只能赋值一次(可以先声明后赋值)
final修饰的是成员变量属性,必须在声明的时候赋值。
全局常量(public staitc final)//随时可以用对象.名称使用
常量命名规范:
由1个或多个单词组成,单词和单词之间必须使用下划线隔开,单
中所有字母大写。例如:SQL_INSERT

final由于修饰类
-----final修饰的类,不可以被继承。
final用于修饰方法
------不能被子类重写

抽象类

抽象类必须使用abstract class声明
一个抽象类中可以没有抽象方法。抽象方法必须写在抽象类或者接口中。

格式:
Abstract class 类名{//抽象类

}

抽象方法

只声明不实现,必须用关键字abstract关键字声明
格式:
Abstract class类名{
Public abstract void 方法名();//抽象方法,声明而不实现。
}

不能被实例化
-----抽象类本身是不能直接进行实例化操作的。即:不能直接关键字nuw完成
一个抽象类必须被子类所继承,而且子类(如果不是抽象类)则必须覆盖实现抽象类中的全部抽象方法

常见问题
1.抽象类能否使用final声明?
不成 , 因为final属修饰的类是不能有子类的,而抽象类必须有子类。
2 .抽象类有构造方法吗?
有的,而且继承的时候子类实例化的时候的流程与普通类的继承是一样的,都是要先调用父类中的构造方法(默认无参数),之后再调用自己的构造方法。

抽象类和普通类的区别

1、抽象类必须用public或procted 修饰(如果为private修饰,那么子类则无法继承,也就无法实现其
抽象方法)。默认缺省为 public
2、抽象类不可以使用new关键字创建对象, 但是在子类创建对象时, 抽象父类也会被JVM实例化。
3、如果一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必
须定义为 abstract类

接口

如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接
口。
定义格式:
interface 接口名称{
全局常量 ;
抽象方法 ;
}

面向接口的编程思想

这种思想是接口是定义(规范,约束)与实现(名实分离的原则)的分离。
优点:
1、降低程序的耦合性 //各模块各自工作,尽量一个模块异常另一个模块不会受到影响
2、 易于程序的扩展
3、 有利于程序的维护

全局常量和抽象方法的简写

因为接口本身都是由全局常量和抽象方法组成 , 所以接口中的成员定义可以简写:
1、全局常量编写时, 可以省略public static final 关键字,例如:
public static final String INFO = “内容” ;
简写后:
String INFO = “内容” ;
2、抽象方法编写时, 可以省略 public abstract 关键字, 例如:
public abstract void print() ;
简写后:
void print() ;

接口实现implements

接口可以多实现:
格式:
class 子类 implements 父接口1,父接口2…{ //可以多继承
}
以上的代码称为接口的实现。那么如果一个类即要实现接口,又要继承抽象类的话,则按照以下的格式编写
即可:
class 子类 extends 父类 implements 父接口1,父接口2…{
}

接口的继承

接口因为都是抽象部分, 不存在具体的实现, 所以允许多继承,例如:
interface C extends A,B{
}

如果一个接口要想使用,必须依靠子类。 子类(如果不是抽象类的话)要实现接口中的所有抽象方法

接口和抽象类的区别

1、抽象类要被子类继承,接口要被类实现。
2、接口只能声明抽象方法,抽象类中可以声明抽象方法,也可以写非抽象方法。
3、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
4、抽象类使用继承来使用, 无法多继承。 接口使用实现来使用, 可以多实现
5、抽象类中可以包含static方法 ,但是接口中不允许(静态方法不能被子类重写,因此接口中不能声明
静态方法)
6、接口不能有构造方法,但是抽象类可以有

多态

多态:就是对象的多种表现形式,(多种体现形态)

多态的体现

对象的多态性,从概念上非常好理解,在类中有子类和父类之分,子类就是父类的一种形态 ,对象多态性
就从此而来。

ps: 方法的重载 和 重写 也是多态的一种, 不过是方法的多态(相同方法名的多种形态)。
重载: 一个类中方法的多态性体现
重写: 子父类中方法的多态性体现。

多态的使用:对象的类型转换
类似于基本数据类型的转换:
· 向上转型:将子类实例变为父类实例
|- 格式:父类 父类对象 = 子类实例 ;
· 向下转型:将父类实例变为子类实例 /不是任何父类都可以转成子类,必须new的时候(开辟空间的时候
就是子类的时候才可以转,简单点说就是你原来是子类的空间可以父转子,原来是父类空间的不可以父转子。
/
|- 格式:子类 子类对象 = (子类)父类实例 ;//括号为强转

instanceof 关键字

作用:
判断某个对象是否是指定类的实例,则可以使用instanceof关键字 //
格式:
实例化对象 instanceof 类 //此操作返回boolean类型的数据
//实例化对象 是不是 这个类型

Object类

Object类是所有类的父类(基类),如果一个类没有明确的继承某一个具体的类,则将默认继承Object
类。
例如我们定义一个类:
public class Person{
}
其实它被使用时 是这样的:
public class Person extends Object{
}

使用Object可以接收任意的引用数据类型
Ps:Object类中具有很多系统写好的方法

toString关键字

建议重写Object中的toString方法。 此方法的作用:返回对象的字符串表示形式。
Object的toString方法, 返回对象的内存地址
重写toString方法,改变返回值,得到自己想要的东西。

equals关键字

建议重写Object中的equals(Object obj)方法,此方法的作用:
指示某个其他对象是否“等于”此对象。
Object的equals方法:实现了对象上最具区别的可能等价关系; 也就是说,对于任何非空引用值x和
y ,当且仅当x和y引用同一对象( x == y具有值true )时,此方法返回true 。
//

equals方法重写时的五个特性:

自反性 :对于任何非空的参考值x , x.equals(x)应该返回true 。 //自己和自己比
对称性 :对于任何非空引用值x和y , x.equals(y)应该返回true当且仅当y.equals(x)回报
true 。//x == y 则 y == x
传递性 :对于任何非空引用值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 。//能调用equals一定不是空

内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
广泛意义上的内部类一般来说包括这四种:

1、成员内部类

依赖于对象 ,只有对象创建的时候才能创建内部类 外部类.内部类 对象名 = 外部类对象名.new 内部类构造函数
在这里插入图片描述

特点: 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默
认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
外部使用成员内部类
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();

2、局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限
于方法内或者该作用域内。
在这里插入图片描述

注意:局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及
static修饰符的。

3、匿名内部类

匿名内部类由于没有名字,所以它的创建方式有点儿奇怪。创建格式如下:
new 父类构造器(参数列表)|实现接口()
{
//匿名内部类的类体部分
}
在这里我们看到使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类
或者实现一个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的
引用。当然这个引用是隐式的。

在使用匿名内部类的过程中,我们需要注意如下几点:

1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能
继承一个类或者实现一个接口。
2、匿名内部类中是不能定义构造函数的。
3、匿名内部类中不能存在任何的静态成员变量和静态方法。
4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6、只能访问final型的局部变量
—为什么局部内部类和匿名内部类只能访问final型的局部变量
因为内部类会被单独被保存为字节码文件。

4、静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。
静态内部类是不需要依赖于外部类对象的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非
static成员变量或者方法.

包装类

在Java中有一个设计的原则“一切皆对象”,那么这样一来Java中的一些基本的数据类型,就完全不符合于这种设计思想,因为Java中的八种基本数据类型并不是引用数据类型,所以Java中为了解决这样的问题,引入了八种基本数据类型的包装类。

在这里插入图片描述
以上的八种包装类,可以将基本数据类型按照类的形式进行操作。
但是,以上的八种包装类也是分为两种大的类型的:
· Number:Integer、Short、Long、Double、Float、Byte都是Number的子类表示是一个
数字。
· Object:Character、Boolean都是Object的直接子类

装箱和拆箱操作

以下以Integer和Float为例进行操作
将一个基本数据类型变为包装类,那么这样的操作称为装箱操作。
将一个包装类变为一个基本数据类型,这样的操作称为拆箱操作,
因为所有的数值型的包装类都是Number的子类,Number的类中定义了如下的操作方法,以下的全部方法都
是进行拆箱的操作。
在这里插入图片描述

装箱操作:

在JDK1.4之前 ,如果要想装箱,直接使用各个包装类的构造方法即可,例如:
int temp = 10 ; // 基本数据类型
Integer x = new Integer(temp) ; // 将基本数据类型变为包装类
在JDK1.5,Java新增了自动装箱和自动拆箱,而且可以直接通过包装类进行四则运算和自增自建操作。例
如:
Float f = 10.3f ; // 自动装箱
float x = f ; // 自动拆箱
System.out.println(f * f) ; // 直接利用包装类完成
System.out.println(x * x) ; // 直接利用包装类完成

字符串转换

使用包装类还有一个很优秀的地方在于:可以将一个字符串变为指定的基本数据类型,此点一般在接收输入
数据上使用较多。
在Integer类中提供了以下的操作方法:
public static int parseInt(String s) :将String变为int型数据
在Float类中提供了以下的操作方法:
public static float parseFloat(String s) :将String变为Float
在Boolean 类中提供了以下操作方法:
public static boolean parseBoolean(String s) :将String变为boolean

额外收获2:

创建一个Scanner 对象 scanner
If(scanner.hasNextInt();)//判断下一个输入的字符是不是int类型

可变参数

一个方法中定义完了参数,则在调用的时候必须传入与其一一对应的参数,但是在JDK 1.5之后提供了新的
功能,可以根据需要自动传入任意个数的参数。
语法:
返回值类型 方法名称(数据类型… 参数名称){
//参数在方法内部 , 以数组的形式来接收
}
注意:
可变参数只能出现在参数列表的最后
递归
递归,在数学与计算机科学中,是指在方法的定义中使用方法自身。也就是说,递归算法是一种直接或者间
接调用自身方法的算法。
递归流程图如下:

递归流程图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值