目录
抽象类
抽象类使用abstract修饰类
抽象类当中可以包含普通类所能包含的成员
抽象类和普通类不一样的是,抽象类当中可以包含抽象方法。
抽象类方法是使用abstract修饰的,这个方法没有具体的实现
不能实例化抽象类
抽象类存在的意义是为了被继承
抽象类的方法不能是私有的(private),要满足重写的规则。
抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员
接口
1.使用interface来修饰接口
2.接口当中的成员方法不能有具体的实现。
在接口中抽象方法默认是public abstract的方法
接口不可以被实例化,也就是说接口不能有静态代码块和构造方法
可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。
接口的使用
实现多个接口
抽象类和接口的区别:
Object类
toString
equals
abstract class Shape{
public int a;
public abstract void draw();
public void func(){
}
}
public class Test {
public static void main(String[] args) {
Shape shape = new Shape();//报错
}
}
如果一个普通类继承了抽象类,此时必须重写抽象类中的方法。
class Rect extends Shape{
@Override
public void draw() {
System.out.println("矩形");
}
}
一个抽象类A继承一个抽象类B,此时不需要重写B中的抽象方法,但当A被继承时,还是要重写B中的抽象方法。
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
interface IShape {
public abstract void func1();
public void func2(){
//报错
}
}
从JDK1.8开始,允许有方法的实现,但是这个方法必须是有default修饰的
可以实现有静态方法
成员变量默认是public static final修饰的,子类如果重写抽象方法必须由public修饰
interface IShape {
public static final int a = 10;
int b = 20;//默认也是public static final修饰的
public abstract void func1();
void func();//默认也是public abstract修饰的
public void func2(){
//报错
}
default public void func3(){
System.out.println("默认方法");
}
public static void func4(){
System.out.println("static修饰的方法");
}
}
public static void main(String[] args) {
IShape ishape = new IShape();//报错
}
class A implements IShape{
public void func1(){
System.out.println("重写抽象方法");
}
}
//USB接口
public interface USB {
void openDevice();
void closeDevice();
}
public class Mouse implements USB{
@Override
public void openDevice() {
System.out.println("打开鼠标");
}
@Override
public void closeDevice(){
System.out.println("关闭鼠标");
}
public void click(){
System.out.println("鼠标点击");
}
}
3. 键盘类:实现USB接口,并具备输入功能
public class KeyBoard implements USB {
@Override
public void openDevice() {
System.out.println("打开键盘");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘");
}
public void inPut(){
System.out.println("键盘输入");
}
}
public class Computer{
public void powerOn(){
System.out.println("打开笔记本电脑");
}
public void powerOff(){
System.out.println("关闭笔记本电脑");
}
public void useDevice(USB usb){
usb.openDevice();
if(usb instanceof Mouse){
Mouse mouse = (Mouse) usb;
mouse.click();
}
if(usb instanceof KeyBoard){
KeyBoard keyboard = (KeyBoard) usb;
keyboard.inPut();
}
usb.closeDevice();
}
}
测试:
//测试
public class TestUsb {
public static void main(String[] args){
Computer computer = new Computer();
computer.powerOn();
computer.useDevice(new Mouse());
computer.useDevice(new KeyBoard());
computer.powerOff();
}
}
interface A{
void func1();
}
interface B{
void func2();
}
class C implements A,B{
@Override
public void func1() {
System.out.println(1);
}
@Override
public void func2() {
System.out.println(2);
}
}
接口实现多继承和多态简单实例
class Animal{
public String name;
public int age;
public Animal(String name,int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("吃饭");
}
}
interface IRuning{
void runing();
}
interface ISwimming{
void swimming();
}
interface IFly{
void fly();
}
class Dog extends Animal implements IRuning,ISwimming{
public Dog(String name,int age){
super(name,age);
}
@Override
public void runing() {
System.out.println(name+"正在跑");
}
@Override
public void swimming() {
System.out.println(name+"正在游泳");
}
}
class Duck extends Animal implements IRuning,ISwimming,IFly{
public Duck(String name,int age){
super(name,age);
}
@Override
public void runing() {
System.out.println(name+"正在跑");
}
@Override
public void swimming() {
System.out.println(name+"正在游泳");
}
@Override
public void fly() {
System.out.println(name+"正在飞");
}
}
public class Test {
public static void walk(IRuning iruning){
iruning.runing();//多态
}
public static void main(String[] args) {
walk(new Dog("小黑",2));
walk(new Duck("可达鸭",3));
}
}
继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性
class Robot implements IRuning{
@Override
public void runing() {
System.out.println("机器人正在跑步");
}
}
public class Test {
public static void walk(IRuning iruning){
iruning.runing();
}
public static void main(String[] args) {
walk(new Dog("小黑",2));
walk(new Duck("可达鸭",3));
walk(new Robot());
}
}
机器人不是动物,但仍然可以实现多态,因为接口只关注某个类是否具有某种能力。机器人有跑步的能力,那他就可以实现。
抽象类可以包含普通字段和成员,接口中不能包含普通方法,子类必须重写所有的抽象方法
抽象方法由普通类(普通字段和方法)和抽象方法组成
接口由抽象方法和全局常量组成
使用extends继承抽象类,使用implements关键字实现接口
一个抽象类可以实现若干个接口,接口不能继承抽象类,接口可以使用extends继承多个父类接口
一个子类只能继承一个抽象类,一个子类可以实现多个接口
Object类是所以类的父类,我们自己写的类就算没有写extends Object,默认也是继承的
class Teacher{
}
class Student{
}
public class Test2 {
public static void func(Object object){
}
public static void main(String[] args) {
func(new Student());//向上转型,不报错
func(new Teacher());
}
}
Object类当中的一些方法:
输出对象的名称,和@符号后面跟一串16进制数字,该数字是由hashCode这个方法产生的
可见Object类中的equals是使用引用中的地址来进行比较的
class Person{
String name;
int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
public class Test3 {
public static void main(String[] args) {
Person per1 = new Person("zhangsan",20);
Person per2 = new Person("zhangsan",20);
int a = 10;
int b = 10;
System.out.println(a==b);
System.out.println(per1==per2);
System.out.println(per1.equals(per2));
}
}
Person类重写equals方法:
class Person{
String name;
int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj==null){
return false;
}
if(this == obj){
return true;
}
if(!(obj instanceof Person)){
return false;
}
Person per = (Person) obj;
if(this.name.equals(per.name) && this.age == per.age){
return true;
}else{
return false;
}
}
}
public class Test3 {
public static void main(String[] args) {
Person per1 = new Person("zhangsan",20);
Person per2 = new Person("zhangsan",20);
int a = 10;
int b = 10;
System.out.println(a==b);
System.out.println(per1==per2);
System.out.println(per1.equals(per2));
}
}