1.抽象类与抽象方法
注意:
抽象类不能实例化
抽线类中不一定有抽i像方法,有抽象方法的类一定是抽象类
可以有构造方法
抽象类的子类要么重写抽象类中的所有抽象方法,要么是抽象类
抽象类的作用:
抽取共性时,无法确定方法体,就把方法定义为抽象的。
强制让子类按照某种格式重写。
抽象方法所在的类,必须是抽象类
抽象类和抽象方法的格式?
public abstract 返回值类型 方法名 (参数列表);
public abstract class 类名{}
抽象类在多态方面的继承:
// 抽象类和抽象方法需要被 abstract 关键字修饰
abstract class Shape {
// 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体
abstract void draw();
}
// 当一个普通类继承一个抽象类后,这个普通类必须重写抽象类中的方法
class Cycle extends Shape {
@Override
void draw() { // 重写抽象类中的draw方法
System.out.println("画一个圆圈");
}
}
public class Test4 {
public static void main(String[] args) {
//Shape shape = new Shape(); 抽象类虽然不能直接实例化
// 但可以把一个普通类对象传给一个抽象类的引用呀,即父类引用指向子类对象
Shape shape = new Cycle(); // 这称作:向上转型
/*Cycle cycle = new Cycle();
Shape shape = cycle // 这是向上转型的另一种写法
*/
shape.draw(); // 通过父类引用调用被子类重写的方法
}
}
2.接口
接口:就是一种规则
例:兔子不会游泳,而青蛙和狗类会,则不能放在父类里,则需要创建一个具有游泳功能的接口。
接口设计规则:
- 抽取派生类的共同属性和行为抽到超类中,
- 抽象类:如果子类方法都一样设计为普通方法,如果子类的行为不是有一致的就写成抽象方法
- 接口:抽取部分子类相同行为,抽取到接口中——多继承,多实现,接口是对单继承的扩展
接口的定义与使用:
//接口定义的关键字interface
//接口都需要有实现类
public interface userService {
//接口中的所有定义都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface timeService {
void timer();
}
//类可以实现接口 implements
//实现了接口的类,就需要重写接口中的方法
//利用接口实现多继承
public class userServiceImpl implements userService,timeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
接口的换代升级:
适用于添加接口新功能
3.内部类
内部类表示的事物是外部类的一部分,内部类单独出现没有任何意义。
内部类的访问特点:
1.内部类可以直接访问外部类的成员,包括私有
2.外部类要访问内部类的成员,必须创建对象
什么时候用到内部类?
例:需要录入车的信息,那么发动机的品牌,颜色,型号就可以当一个内部类
下图中Engine为内部类
内部类主要分为:静态内部类,非静态内部类。(static静态修饰)
注意:非静态内部类里不能有静态方法,静态成员变量,静态初始化块。
main获取内部类的对象:
1.Car.Engine r=new Car().new.Engine();直接创建(格式:外部类名.内部类名 对象名=外部类对象.内部类对象)
2.外部类编写方法,对外部类提供内部对象(private)
非静态外部类访问内部类
public class jtai {
private String prop="外部变量";
private class InClass {
private String prop = "内部变量";
public void print() {
String prop = "局部变量";
System.out.println("外面 " + jtai.this.prop);
System.out.println("内部 " + this.prop);
System.out.println("局部 " + prop);
}
}
public void test() {
InClass obj=new InClass();
obj.print();
}
public static void main(String[] args) {
new jtai().test();
}
}
非静态内部类访问外部类
// 外部类
class OuterClass {
private int outerField = 10;
// 内部类
class InnerClass {
void accessOuter() {
System.out.println("访问外部类的成员变量: outerField = " + outerField);
System.out.println("调用外部类的方法:");
outerMethod();
}
}
// 外部类的方法
void outerMethod() {
System.out.println("这是外部类的方法");
}
// 外部类的入口方法
public static void main(String[] args) {
// 创建外部类的对象
OuterClass outerObj = new OuterClass();
// 创建内部类的对象
OuterClass.InnerClass innerObj = outerObj.new InnerClass();
// 调用内部类访问外部类的方法
innerObj.accessOuter();
}
}
静态内部类:只能访问外部类中的静态变量和静态方法,如果想要访问非静态的想要创建对象。
静态内部类访问外部类:
// 外部类
class OuterClass {
private static int outerStaticField = 100;
private int outerField = 10;
// 静态内部类
static class StaticInnerClass {
void accessOuter() {
// 访问外部类的静态成员变量
System.out.println("访问外部类的静态成员变量: outerStaticField = " + OuterClass.outerStaticField);
// 若要访问外部类的非静态成员变量,需要通过外部类的对象访问
OuterClass outerObj = new OuterClass();
System.out.println("访问外部类的非静态成员变量: outerField = " + outerObj.outerField);
// 若要调用外部类的方法,也需要通过外部类的对象访问
outerObj.outerMethod();
}
}
// 外部类的方法
void outerMethod() {
System.out.println("这是外部类的方法");
}
// 外部类的入口方法
public static void main(String[] args) {
// 创建静态内部类的对象
StaticInnerClass innerObj = new StaticInnerClass();
// 调用内部类访问外部类的方法
innerObj.accessOuter();
}
}
外部类访问静态内部类
// 外部类
class OuterClass {
private static int outerStaticField = 100;
// 静态内部类
static class StaticInnerClass {
void innerMethod() {
System.out.println("这是静态内部类的方法");
}
}
// 外部类的方法
void outerMethod() {
System.out.println("这是外部类的方法");
// 在外部类的方法中创建静态内部类的对象并调用其方法
StaticInnerClass innerObj = new StaticInnerClass();
innerObj.innerMethod();
}
// 外部类的入口方法
public static void main(String[] args) {
// 在外部类的静态方法中创建静态内部类的对象并调用其方法
StaticInnerClass innerObj = new StaticInnerClass();
innerObj.innerMethod();
// 在外部类的静态方法中创建外部类的对象并调用其方法
OuterClass outerObj = new OuterClass();
outerObj.outerMethod();
}
}
有没有发现一个现象即静态与非静态的相互访问都需要用到关键字new,因为静态会开辟空间,呢哇也是。
注意:使用静态内部类比使用非静态内部类简单很多,只要把外部类当成静态内部类的包空间即可。