这里把抽象类、接口及内部类放在一起介绍在于其实三者都属于类,只不过可以把接口看做特殊的类,对三年者之间的特点和区别进行详细的分析。首先介绍抽象类,顾名思义抽象类就是把一个类进行抽象化,必须使用abstract关键字修饰,抽象类是一个没有完成的类,不能被实例化(不能创建抽象类对象)。注意点:有抽象方法的类一定是抽象类,但抽象类中不一定有抽象方法。这里提到的抽象方法指的是抽象类中使用abstract关键字修饰没有方法体的方法,抽象方法必须被继承抽象类的子类进行重写,但一个类只能继承一个抽象类。抽象类的作用:抽象类往往用来表达我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。在面向对象过程中模块可以操作一个抽象体,但由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展模块的行为功能,提高代码复用。下面提供一个抽象类案例供大家理解:
源代码如下:
1.首先定义一个抽象学生类和抽象方法writeMain()
public abstract class Student {
// 用于描述文章的方法
public void write() {
System.out.println("《我的世界风雪有你》");
System.out.println("江雪儿");
System.out.println(writeMain());
System.out.println("罗易寒");
}
// 定义一个抽象方法用于处理后期不同的需求
abstract String writeMain();
}
2.定义两个类继承抽象学生类并重写抽象方法
// 继承抽象类,重写抽象方法
public class StudentChild extends Student{
@Override
String writeMain() {
return "要么出彩,要么出局";
}
}
// 继承抽象类,重写抽象方法
public class StudentMiddle extends Student {
@Override
String writeMain() {
return "江雪无情,星罗易寒";
}
}
3.生成对象调用方法
public class Test {
public static void main(String[] args) {
// 创建对象,调用方法
StudentChild s1 = new StudentChild();
s1.write();
Student s2 = new StudentMiddle();
s2.write();
}
}
4.运行结果
现在介绍接口,其实相比抽象类实际应用中使用接口的概率往往更大,接口由关键字interface修饰,jdk1.8之前接口中的常量全是公有静态常量,默认由public static final 修饰,方法默认由public abstract修饰,所以接口和抽象类一样不能被实例化,实现接口的类必须重写接口中的抽象方法,与抽象类不同的是实现接口的类可以实现多个不同的接口,这与抽象类的直接单继承有所区别。由此可以退出实现类可以在实现多接口的同时继承一个父类但需要注意的是实现类必须先继承在实现接口,否则会出现编译错误。格式如下:public class 实现类 extends 父类 implements 接口名称,接口名称 { }。接口在面向对象程序中的作用:1.最主要的作用就是解耦,接触代码之间的高度耦合性,也就是让每个功能相互独立 2.接口可以实现不相关类的相同行为,而不需要了解对象所对应的类 3.接口可以指明多个类需要实现的方法,因为实现接口的类必须实现接口中的抽象方法。
总结抽象类和接口的区别:
(1)抽象类中提供成员方法的实现细节,接口中只能是public abstract修饰,即只能是抽象方法。
(2)抽象类中成员变量可实现多种权限public private protected final 等,接口中只能用public static final修饰。
(3)抽象类中可以有静态方法和静态代码块,接口中不能有静态方法和静态代码块。
(4)抽象类是单继承多实现。接口可以继承多个接口。
最后介绍内部类,内部类见名知意,就是在一个类的内部再建立一个类,该类被称为内部类,内部类分为非静态内部类(即没有使用static修饰的内部类)、静态内部类(即使用static修饰的内部类)、局部内部类、匿名内部类。根据实际应用中应用最广泛的情况,这里只对匿名内部类进行解读和非静态内部类展示,如果对其他几类感兴趣可以查找其他资料进行深度学习。匿名内部类适合创建那种只需要一次使用的类,如果多次创建每次都会产生一个新的对象,会导致内存空间的浪费,这源于匿名内部类的特点该类定义立即消失,不能重复使用。创建匿名内部类的规则:1、匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。 2、匿名内部类不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。 3、匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器。匿名内部类的特点:定义匿名内部类无需class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象,当通过实现接口来创建匿名内部类时,匿名内部类也不能显式创建构造器,因此匿名内部类只有一个隐式的无参构造器,故new接口名后的括号里不能传入参数值。
但如果通过继承父类来创建匿名内部类时,匿名内部类将拥有相似的构造器。此处的相似指拥有相同的形参列表。下面提供一个内部类案例供大家参考:
源代码如下:
1.定义一个奶牛类并在该类中再定义一个奶牛腿类,即为内部类
public class Cow {
private double weight;
private String prop = "外部类的成员变量";
// 非静态内部类(相当于普通成员属性)
public class CowLeg {
private double length;
private String color;
private String prop = "内部类的成员变量";
public CowLeg(double length, String color) {
this.length = length;
this.color = color;
}
public CowLeg() {
}
// 信息显示
public void showInfo() {
String prop = "内部类的局部变量";
// 非静态的内部类成员方法可以访问外部类私有的成员属性
System.out.println("牛的体重为" + weight + "牛的长度为:" + length + "牛的颜色为" + color);
// 内部类中属性与外部类属性重名访问
System.out.println(Cow.this.prop + " " + this.prop + " " + prop);
}
}
public Cow() {
}
public Cow(double weight) {
this.weight = weight;
}
// 外部类的成员方法
public void Info() {
CowLeg cowLeg = new CowLeg();
cowLeg.showInfo();
}
}
2.生成外部类对象或内部类对象访问内部类信息
public class Test {
public static void main(String[] args) {
// 访问内部类(通过调用外部类的成员方法访问内部类)
Cow cow = new Cow();
cow.Info();
// 访问内部类(通过直接创建内部类对象访问内部类)
Cow.CowLeg cowLeg = new Cow().new CowLeg();
cowLeg.showInfo();
}
}
3.运行结果
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net