抽象类和接口有什么区别?
- 一个类只能继承一个抽象类;但一个类可以实现多个接口。所以我们在新建线程类的时候,一般推荐使用Runnable接口的方式,这样线程类还可以继承其他类,而不单单是Thread类;
- 抽象类符合is-a的关系,而接口更像是has-a的关系,比如说一个类可以序列化的时候,它只需要实现Serializable接口就可以了,不需要去继承一个序列化类;
- 抽象类更多地是用来为多个相关的类提供一个共同的基础框架,包括状态的初始化,而接口则是定义一套行为标准,让不同的类可以实现同一个接口,提供行为的多样化实现;
那么,抽象类可以定义构造方法吗?
- 可以,抽象类是可以有构造方法的;
abstract class Animal {protected String name;public Animal(String name) {this.name = name;}public abstract void makeSound();
}public class Dog extends Animal {private int age;public Dog(String name, int age) {super(name); // 调用抽象类的构造函数this.age = age;}@Overridepublic void makeSound() {System.out.println(name + " says: Bark");}
}
那么,接口可以定义构造方法吗?
- 不能,接口主要用于定义一组方法规范,没有具体的实现细节;
再问一句,Java支持多继承吗?
- Java不支持多继承,一个类只能继承一个类,多继承会引发菱形继承问题;
class A {void show() { System.out.println("A"); }
}class B extends A {void show() { System.out.println("B"); }
}class C extends A {void show() { System.out.println("C"); }
}// 如果 Java 支持多继承
class D extends B, C {// 调用 show() 方法时,D 应该调用 B 的 show() 还是 C 的 show()?
}
接口可以多继承吗?
- 接口可以多继承,一个接口可以继承多个接口,使用逗号分隔;
interface InterfaceA {void methodA();
}interface InterfaceB {void methodB();
}interface InterfaceC extends InterfaceA, InterfaceB {void methodC();
}class MyClass implements InterfaceC {public void methodA() {System.out.println("Method A");}public void methodB() {System.out.println("Method B");}public void methodC() {System.out.println("Method C");}public static void main(String[] args) {MyClass myClass = new MyClass();myClass.methodA();myClass.methodB();myClass.methodC();}
}
在上面的例子中,InterfaceA 和 InterfaceB 是两个独立的接口。
InterfaceC 继承了 InterfaceA 和 InterfaceB,并且定义了自己的方法 methodC。
MyClass 实现了 InterfaceC,因此需要实现 InterfaceA 和 InterfaceB 中的方法 methodA 和 methodB,以及 InterfaceC 中的方法 methodC。
继承和抽象的区别是什么呢?
- 继承是一种允许子类继承父类属性和方法的机制,通过继承,子类可以重用父类的代码。
- 抽象是一种隐藏复杂性和只显示必要部分的技术。在面向对象编程中,抽象可以通过抽象类和接口实现;
那么,我好奇,抽象类和普通类的区别是什么呢?
- 抽象类使用abstract关键字定义,不能被实例化,只能作为其他类的父类。普通类没有abstract关键字,可以直接实例化;
- 抽象类可以包含抽象方法和非抽象方法。抽象方法没有方法体,必须由子类实现。普通类只能包含非抽象方法;
abstract class Animal {// 抽象方法public abstract void makeSound();// 非抽象方法public void eat() {System.out.println("This animal is eating.");}
}class Dog extends Animal {// 实现抽象方法@Overridepublic void makeSound() {System.out.println("Woof");}
}public class Test {public static void main(String[] args) {Dog dog = new Dog();dog.makeSound(); // 输出 "Woof"dog.eat(); // 输出 "This animal is eating."}
}
接下来,忽然想到了Java中的final关键字,那就一并回顾复习下吧
final关键字有什么用呢?
- 当final修饰一个类时,表明这个类不能被继承。比如,String类,Integer类和其他包装类都是用final修饰的;
- 当final修饰一个方法时,表明这个方法不能被重写Override。也就是说,如果一个类继承了某个类,并且想要改变父类中被final修饰的方法的行为,是不被允许的;
如果是基本数据类型的变量,其数值一旦在初始化之后就不能更改;如果是引用类型的变量,在对其初始化之后就不能再让其指向另一个对象,但是引用指向的对象内容可以改变;