抽象类与抽象方法:
1. 方法在本类中不实现,而是在子类中实现的方法,可以在该方法和类的声明中加入abstract修饰符,将该方法和类标记为抽象的
2. 包含一个抽象方法的类必须定义为抽象类
3. 抽象类和抽象方法都要使用abstract关键字声明
4. 抽象方法只需要声明而不需要实现
5. 抽象类必须被子类继承,子类(如果不是抽象类)必须覆写抽象类中的全部抽象方法
6. 构造方法、静态方法、私有方法、final方法不能被声明为抽象方法
public abstract class Abstract {
public void test1() {//普通方法不需要被覆写,即使调用了抽象方法也不需要
test2();
};
public abstract void test2();
public abstract void test3();
}
class Abstract1 extends Abstract {//子类不是抽象类,必须覆写父类所有的抽象方法
@Override
public void test2() {
}
@Override
public void test3() {
}
}
abstract class Abtract2 extends Abstract {//子类是抽象类,可以选择性覆写父类的抽象方法
@Override
public void test2() {
}
}
class Abtract extends Abtract2 {//普通方法再继承,则必须覆写父类没有覆写过的祖辈的抽象方法
@Override
public void test3() {
}
}
7. 抽象类中允许存在构造方法,且子类对象实例化之前同样会默认调用父类中的无参构造
接口:
1. 类似于类,是纯抽象类,不规定其实现,由全局常量和公共的抽象方法组成,也就是说接口中的所有方法都是抽象的,必须定义为public,即使不写也是public访问权限
2. 类只能继承一个父类,却可以实现多个接口
3. 接口可以继承另外的接口(可以不止一个)
public interface Interface {
int a=1;//等价于:public static final int a = 1;
void test();//等价于:public abstract void test();
}
interface Interface1{
void test1();
}
interface Interface2 extends Interface,Interface1{//接口可以继承多个接口
void test2();//接口可以不覆写继承的接口中的抽象方法
}
interface Interface3{
void test3();
}
class Test implements Interface1{//实现接口
@Override
public void test1() {//实现接口中的抽象方法
}
}
class Test1 implements Interface2{//实现接口
@Override
public void test() {//需要实现所有的抽象方法
}
@Override
public void test1() {
}
@Override
public void test2() {
}
}
class Test2 implements Interface2,Interface3{//子类同时实现两个接口
@Override
public void test() {//需要覆写所继承的接口中的所有抽象方法
}
@Override
public void test1() {
}
@Override
public void test3() {
}
@Override
public void test2() {
}
}
abstract class Test3 implements Interface2,Interface3{//抽象类实现接口
@Override
public void test2() {//选择性覆写所继承接口中的抽象方法
}
}
class Test4 extends Test3{//继承抽象类
@Override
public void test() {//需要实现父类没有继承过的祖类的抽象方法
}
@Override
public void test1() {
}
@Override
public void test3() {
}
}
内部类:
1. 在一个类或方法中定义另外一个类,这个类就叫做内部类或内置类,内部类对象可以随意的访问外部类中所有的成员
2. 在方法中定义的内部类,如果要访问方法中定义的本地变量或方法的参数,则变量必须被声明final
3. 内部类可以声明为private或protected,也声明为abstract或final;但如果声明为static的,就不能再使用外部类的非static的成员变量和非static的成员方法
4. 在外部访问一个类的内部类,首先要找到外部类的实例化对象,再通过外部类的实例化对象去实例化内部类的对象
public class OuterClass {
Animal animal;
static int a=1;
int b=2;
public OuterClass(){//构造方法
animal=new Dog();//实例化子类
}
public void test(){
// OuterClass oc = new OuterClass();
// oc.speak(animal);//不能调用外部类
new InnerClass().speak();//可以调用内部类的方法
int x=1;
final int y=2;
class InnerClass2{//方法中的内部类
public void test(final int m){
// int z=x+1;//在方法中定义的内部类,如果要访问方法中定义的本地变量或方法的参数,则变量必须被声明final
int v=y+1;
int d=y+m;
}
}
}
public class InnerClass{//内部类
public void speak() {
animal.speak();
}
// public static void test(){// 非static的内部类中的成员不能声明为static的,只有在顶层类或static的内部类中才可声明static成员
// };
}
public static class InnerClass1{
public void test(){
// animal.speak();// 内部类可以声明为static的,此时就不能再使用外部类的非static的成员变量和非static的成员方法
int c=a+1;
// int d=b+1;
}
}
}
abstract class Animal {//抽象外部类Animal
public abstract void speak();
}
class Dog extends Animal{//继承抽象类
@Override
public void speak() {
System.out.println("汪汪汪");
}
}
class OuterClass1{//外部类
public void speak(Animal animal) {
animal.speak();
}
//在外部访问一个类的内部类
OuterClass out =new OuterClass();//首先实例化外部类对象
OuterClass.InnerClass in = out.new InnerClass();//通过外部类的实例化对象去实例化内部类的对象
}
匿名内部类:没有名字的类,这个类在定义的时候被实现
public class InnerClassTest {
public static void main(String[] args) {
new X().fun1();//实例化X类对象并调用fun1方法
}
}
interface I{//定义接口I
public void printInfo();//定义抽象方法
}
class X{//定义X类
public void fun1(){
this.fun2(new I(){//匿名内部类
public void printInfo(){//实现接口中的抽象方法
System.out.println("Hello World!");
}
});
}
public void fun2(I a){//接收接口实例
a.printInfo();//调用接口方法
}
}