目录
1、前言
又到了周末,首先祝大家周末快乐,端午安康。端午期间,没少和朋友闲谈,听到了不少的抱怨。。。在这里,送大家十六个字“物来顺应,当时不迎,当时不杂,既过不恋”,有的事过去了就让它过去了,再多说难过的只是自己。闲暇之余多运动运动,或者充充电,都是极好的。话不多说,直接上干货。
2、包装类
Java中一切皆对象?数据类型的划分为基本数据类型和引用数据类型,但基本数据类型怎么成为对象呢?为解决这个问题,包装类就起了作用。
2、1 包装类的基本类型
每一个数据类型都有其对应的包装类。Java包含了8种基本数据类型,由于这八种基本数据类型不支持面向对象的编程机制。因而Java语言另外提供了对应的8基本数据类型的包装类,来实现面向对象机制。
2、2 装箱与拆箱
- 装箱: 将一个基本数据类型变为包装类,这样的过程称为装箱操作
- 拆箱: 将一个包装类变为基本数据类型这样的过程称为拆箱操作
我们以Integer和Float为例,举个栗子。
public class Demo01{
public static void main(String args[]){
Integer n=new Integer(100); // 装箱操作
System.out.println(n.intValue()); //拆箱操作并输出
Double dObj=new Double(123.0); // 装箱操作
double d=dObj.doubleValue(); //拆箱操作
System.out.println(d);
Boolean bObj=new Boolean(true); // 装箱操作
boolean b=bObj.booleanValue(); //拆箱操作
System.out.println(b);
Character cObj=new Character('A'); // 装箱操作
char c=cObj.charValue(); //拆箱操作
System.out.println(c);
}
}
包装类在实际中用得最多的还在于字符串变为基本数据类型的操作上,例如:将一个全由数字组成的字符串变为一个int或float类型的数据。例如,把字符串变换为基本的数据类型
public class Demo02{
public static void main(String[] args) {
String str1 = "30" ; // 由数字组成的字符串
String str2 = "30.3" ; // 由数字组成的字符串
int x = Integer.parseInt(str1) ; // 将字符串变为int型
float f = Float.parseFloat(str2) ;// 将字符串变为float型
System.out.println("整数乘方:" + x + " * " + x + " = " + (x * x));
System.out.println("小数乘方:" + f + " * " + f + " = " + (f * f));
}
}
3、抽象类
3.1 抽象方法和抽象类
abstract,中文译为“抽象”,其可以理解为概括性的,或不具体、不完善的含义。
abstract 可以修饰类和方法,分别称为抽象类和抽象方法。
- (1)用abstract修饰的类称为抽象类。 abstract class AbClass { …… }
- (2)用abstract修饰,没有实现细节的方法(只有方法声明,无方法体)被称为抽象方法。 abstract void abFunc();
3.2 抽象类的格式
abstract class 抽象类名称{
属性 ;
访问权限 返回值类型 方法名称(参数){ // 普通方法
[return 返回值] ;
}
访问权限 abstract 返回值类型 方法名称(参数) ; // 抽象方法
// 在抽象方法中是没有方法体的
}
我们接着举个例子来看看
/**
* 抽象类
*/
abstract class Pets{
public abstract void voice();
//吃东西
public abstract void eat();
}
//如果父类中有抽象方法,则·子类必须实现父类的抽象方法
class Dod extends Pets{
@Override
public void voice() {
System.out.println("汪汪叫");
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Pets{
@Override
public void voice() {
System.out.println("喵喵叫");
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
3.3 抽象类的注意事项
抽象方法不能创建对象(不能实例化)
抽象类中可以没抽象方法,有抽象方法的类一定是抽象类
子类重写父类时,必须重写父类所有的抽象方法
3.4 抽象类的使用
范例:
abstract class A{//定义一个抽象类
public void fun(){//普通方法
System.out.println("存在方法体的方法");
}
public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
public class Demo03{
public static void main(String[] args) {
A a = new A();
}
}
运行结果:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot instantiate the type A
at com.wz.abstractdemo.TestDemo.main(TestDemo.java:15)
那么,为什么会出现这样的情况呢?从上可知,A是抽象的,无法直接进行实例化操作。为什么不能直接实例化呢?当一个类实例化之后,就意味着这个对象可以调用类中的属性或者放过了,但在抽象类里存在抽象方法,而抽象方法没有方法体,没有方法体就无法进行调用。既然无法进行方法调用的话,又怎么去产生实例化对象呢。
3.5 抽象类的使用原则
- 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
- 抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
- 抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
- 子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
范例:
abstract class A{//定义一个抽象类
public void fun(){//普通方法
System.out.println("存在方法体的方法");
}
public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类
@Override
public void print() {//强制要求覆写
System.out.println("Hello World !");
}
}
public class Demo04 {
public static void main(String[] args) {
A a = new B();//向上转型
a.print();//被子类所覆写的过的方法
}
}
运行结果:
Hello World !
由此可知,
- 抽象类继承子类里面有明确的方法覆写要求,而普通类可以有选择性的来决定是否需要覆写;
- 抽象类实际上就比普通类多了一些抽象方法而已,其他组成部分和普通类完全一样;
- 普通类对象可以直接实例化,但抽象类的对象必须经过向上转型之后才可以得到。
虽然一个类的子类可以去继承任意的一个普通类,可是从开发的实际要求来讲,普通类尽量不要去继承另外一个普通类,而是去继承抽象类。
3.6 抽象类总结
- 一定要掌握抽象类定义格式及使用规则
- 抽象类使用的时候一定要有子类,子类仍然使用extends关键字继承一个抽象类,同样会存在单继承的关系。
- 一个子类不能同时继承多个抽象类
- 抽象类中绝对不能使用final关键字声明 抽象类中允许有构造方法,而且完全符合子类对象的实例化过程。
4、接口
4.1 接口的定义格式及使用
接口是java中最重要的概念,接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。
接口实现了多重继承的功能 ,其格式如下:
[public] interface 接口名 [extends 父接口名列表]
{
[public] [static] [final] 常量声明 //全局常量
[public] [abstract] 方法声明 //抽象方法
}
接口的定义
- 接口里不能包含构造器、变量。可以包含常量、方法(抽象方法)、内部类。
- 接口里定义的常量系统默认使用public static final修饰符修饰。由于接口没有构造器,所以这些常量必须在定义的时候指定默认值
- 对于接口定义的方法而言,它们只能是抽象方法,因此系统会自动为其增加abstract修饰符;由于接口里的方法全部是抽象方法,因此接口不允许定义静态方法,即不可使用static修饰接口里定义的方法,一般使用public abstract来修饰。
实现接口
与抽象类一样,接口要使用也必须通过子类,子类通过implements关键字实现接口。
一个类要实现某个接口,必须实现该接口的所有方法,方法的名字、返回值类型、参数个数及类型必须与接口中定义的方法完全一致,并一定要用public修饰,否则,该类将保留从父类接口那里继承到的抽象方法,该类也必须定义成抽象类。
实现格式:
class 子类 implements 接口A,接口B,...{
}
下面照例 举个栗子
interface IsShape2D{
public double PI =3.1415926 ; // 定义全局常量
public double area() ; // 定义抽象方法
public double perimeter() ; // 定义抽象方法
}
interface IsShape3D{
public double dulk() ; // 定义抽象方法
}
class Circle implements IsShape2D, IsShape3D{// 子类同时实现两个接口
private double r;
public Circle(double r){
this.r=r;
}
public double area() { // 覆写IsShape2D接口中的抽象方法
return PI*r*r;
}
public double perimeter() { // 覆写IsShape2D接口中的抽象方法
return 2*PI*r;
}
public double dulk() { // 覆写IsShape3D接口中的抽象方法
return 4/3*PI*r*r*r;
}
}
4.2 抽象继承类实现接口
一个子类可以同时继承抽象类和实现接口。
格式如下:
class 子类 extends 抽象类 implements 接口A,接口B,...{}
继续举例
abstract class IsShape2D{
public static final double PI =3.1415926 ; // 定义全局常量
public abstract double area() ; // 定义抽象方法
public abstract double perimeter() ; // 定义抽象方法
}
interface IsShape3D{
public double dulk() ; // 定义抽象方法
}
class Circle extends IsShape2D implements IsShape3D{//子类继承抽象类同时实现一个接口
private double r;
public Circle(double r){
this.r=r;
}
public double area() { // 覆写IsShape2D抽象类中的抽象方法
return PI*r*r;
}
public double perimeter() { // 覆写IsShape2D抽象类中的抽象方法
return 2*PI*r;
}
public double dulk() { // 覆写IsShape3D接口中的抽象方法
return 4/3*PI*r*r*r;
}
}
4.3 接口的继承
一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口,实现接口的多继承,即一个接口可以有多个直接父接口。一个接口继承多个父接口时,多个父接口排在extends关键字之后,多个父接口之间以英文逗号隔开。
格式:
interface 子接口 extends 父接口A,父接口B,...{}
举例:
interface IsShape2D{
public double PI =3.1415926 ; // 定义全局常量
public double area() ; // 定义抽象方法
}
interface IsShape3D{
public double dulk() ; // 定义抽象方法
}
interface Shape extends IsShape2D, IsShape3D{ //接口的多继承
public double perimeter() ; // 定义抽象方法
}
class Circle implements Shape{ // 子类实现接口
private double r;
public Circle(double r){
this.r=r;
}
public double area() { // 覆写IsShape2D接口中的抽象方法
return PI*r*r;
}
public double perimeter() { // 覆写Shape接口中的抽象方法
return 2*PI*r;
}
public double dulk() { // 覆写IsShape3D接口中的抽象方法
return 4/3*PI*r*r*r;
}
}