1 抽象方法和抽象类
抽象方法:使用 abstract修饰的方法,没有方法体,只有声明,定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现
抽象类:包含抽象方法的类就是抽象类,通过abstract方法定义规范,然后要求子类必须定义具体实现,通过抽象类,可以做到严格限制子类的设计,使子类更加通用
package cn.coisini.oop;
public abstract class Animal {
//1,抽象方法没有实现,2,子类必须实现抽象方法否则报错
abstract public void shout();
public void run() {
System.out.println("run!");
}
public static void main(String[] args) {
Animal a = new Dog(); //不能new抽象类自己
}
}
class Dog extends Animal {
public void shout() {
System.out.println("shout!");
}
}
抽象类的使用要点:
1,有抽象方法的类只能定义成抽象类
2,抽象类不能实例化,即不能用new来实例化抽象类
3,抽象类可以包含属性,方法,构造方法,但是构造方法不能用来new实例,只能用来被子类调用
4,抽象类只能用来被继承
5,抽象方法必须被子类实现
抽象类存在的意义在于给子类提供一个统一的,规范的设计模板,子类必须实现相关的抽象方法
2 接口
接口内的所有方法都是抽象方法,不需要再abstract声明
接口就是比 “抽象类” 还要 “抽象” 的"抽象类",可以更加规范的对子类进行约束,全面专业地实现了:规范和具体实现的分离,接口只定义了规范,不定义具体的实现
接口的本质:
接口就是规范,定义一组规则,体现了"如果你是…则必须能…"的思想,即如果你是鸟,则必须能飞,如果你是车,则必须能跑,接口的本质是契约,制定好后如同法律,大家都遵循
面向对象的精髓,是对对象的抽象,最能体现这一点的就是接口,接口可以实现多继承
接口的声明:
[访问修饰符] interface 接口名 [extends 父接口1,父接口2] {
常量定义;
方法定义;
}
定义接口的详细说明:
1,访问修饰符:只能是public或默认
2,接口名:和类名采用相同的命名机制
3,extends:接口可以多继承
4,常量:接口中的属性只能是常量,总是public static final
5,方法:接口中的方法只能是抽象方法,总是public abstract
package cn.coisini.oop;
public interface MyInterface {
int MAX_AGE = 100; //接口中只能定义常量,默认加上了 public static final
void test01(); //接口中的方法都是抽象方法,默认加上了 public abstract
}
class MyClass implements MyInterface {
@Override
public void test01() {
System.out.println("Interface");
System.out.println(MAX_AGE);
}
}
要点:
1,子类通过implements来实现接口中的规范
2,接口不能创建实例,但是可以用于声明引用变量类型
3,一个类实现了接口,必须实现接口中的所有方法,且这些方法都是public类型的
接口可以多继承
package cn.coisini.oop;
public interface TestInterface2 {
}
interface A {
void testa();
}
interface B {
void testb();
}
//接口可以多继承,接口C继承接口A和B
interface C extends A,B {
void testc();
}
class MysubClass implements C {
@Override
public void testa() {
}
@Override
public void testb() {
}
@Override
public void testc() {
}
}
3 面向接口编程
面向接口编程是面向对象编程的一部分
为什么需要面向接口编程?软件中最难处理的就是需求的复杂变化,需求的变化体现在具体实现上,我们编程时围绕具体实现时,就会陷入复杂变化的境地,必须围绕着某种指定的东西开展,实现规范的该质量项目
接口就是规范,通过面向接口编程,而不是面向实现类编程,可以大大降低程序间的耦合性,提高整个系统的可维护性和可扩展性
4 内部类
在JAVA中内部类主要分为 成员内部类(非静态内部类,静态内部类),匿名内部类,局部内部类
非静态内部类:
1,非静态内部类必须寄存在一个外部类对象里
2,非静态内部类可以直接访问外部类的成员,但外部类不能直接访问非静态内部类成员
3,非静态内部类不能有静态方法,静态属性和静态初始化块
package cn.coisini.oop;
/**
* 测试非静态内部类
* @author coisini1999
*
*/
public class TestInnerClass {
public static void main(String[] args) {
//内部类对象的建立
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
class Outer {
private int age = 10;
public void testOuter() {
System.out.println("");
}
//非静态内部类
class Inner {
int age = 20;
public void show() {
int age = 30;
System.out.println("外部类的成员变量:"+Outer.this.age);
System.out.println("内部类的成员变量:"+this.age);
System.out.println("局部变量:"+age);
}
}
}
静态内部类:
1,用static修饰,可以看作一个静态内部类对象存在,不一定需要对应的外部类
2,静态内部类看作一个静态成员,因此,外部类的方法可以通过“静态内部类.名字”的形式访问静态内部类的静态成员,通过new 静态内部类()访问静态内部类的实例
package cn.coisini.oop;
public class TestStcticInner {
public static void main(String[] args) {
Outer2.Inner2 inner = new Outer2.Inner2();
}
}
class Outer2 {
static class Inner2 {
}
}
匿名内部类:
1,适合那种只需要使用一次的类,如键盘监听操作等等
2,匿名内部类没有访问修饰符和构造方法
局部内部类:
定义在方法内部,作用域只局限于本方法,称为局部内部类,应用较少