zoukankan      html  css  js  c++  java
  • luogg_java学习_07_抽象类_接口_多态学习总结

    这篇博客总结了半天,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用.
    **转载请注明 出自 : luogg的博客园 ** ,

    抽象

    一种专门用来做父类,被继承的. (模板)

    格式:

    abstract class 抽象类名{
    	属性;
    	普通方法;
    	访问权限 abstract 返回值类型 方法名称([形参]);//抽象方法,无方法体
    }
    

    这里写图片描述

    抽象类中, 不写访问权限的时候, 默认是default, 不同于接口中的默认(接口方法默认被public abstract 修饰), 子类在继承抽象类时候, 需要重写抽象类中方法, 修饰符可以默认不写(default)或者写public , 但在接口中重写时必须为public

    抽象类的定义及使用:

    1, 定义父类为抽象类,并定义没有方法体的抽象方法
    2, 子类继承抽象类, 并重写父类的抽象方法,写入方法体,去掉abstract

    使用抽象类注意事项:

    1, 抽象类本身不可以创建对象, 因为它不可以被实例化,即不能构造一个该类的对象.
    2, 抽象类有构造方法, 在子类实例化前也会默认的调用它的无参构造方法, 只要是类, 都有构造方法
    3, **抽象类中不一定要有抽象方法,但是有抽象方法的类, 一定要被声明为抽象类,不然编译不通过 **
    4, abstract只能修饰类和方法
    abstract 不能用来修饰属性, 构造器, 不能与private , final , static 共用

    • 属性不能被覆盖,重写,
    • 构造器不能被重写
    • private只能在本类中调用,不能被继承,不能被重写
    • fianl修饰方法,不能被重写 , 修饰类, 不能被继承

    抽象类与普通类的区别

    这里写图片描述

    接口

    概念

    接口可以理解为一种特殊的抽象类, 对行为的抽象, 由全局常量和公有抽象方法组成 , 接口的作用是用来被实现的(implement) , 接口属于复合类型,

    定义

    [访问修饰符] interface I接口名{
    	属性(全局常量,默认被static final修饰);
    	抽象的方法(没有方法体,方法默认被public abstract修饰);
    }
    

    这里写图片描述

    注意事项:

    1, 子类实现接口,重写方法的时候,修饰符必须加public,当接口中用默认的时候,因为接口方法默认是public+abstract修饰的
    2, 接口没有构造方法,没有办法创建对象
    3, 接口名字必须以大写I开头
    4, 接口的作用是为了弥补java中的单继承,接口之间可以多extends,
    5, 接口不可以继承抽象类, 但是接口可以extends 多个接口, 抽象类可以implements接口,普通类可以implements多个接口

    接口和抽象的混搭使用

    当子类既要继承抽象类 , 又要实现接口的时候, 先extends 抽象类, 然后再 implements 接口1,接口2..{}

    public class Test2 {
    	public static void main(String[] args) {
    		P p1 = new P();
    		p1.tell2();
    //		static修饰的age,静态全局常量,
    		System.out.println(I1.age);
    		System.out.println(I2.age);
    		System.out.println(I3.age);
    		
    		p1.tell1("花花");
    		p1.tell1();
    	}
    }
    //定义一个抽象类
    abstract class Abs1 implements I1,I2{//抽象类可以implements多个接口,但是不可以extends接口
    	String name;
    //	抽象类可以有构造方法
    	Abs1() {
    		
    	}
    	Abs1(String name){
    		
    	}
    	abstract void tell1();
    }
    //定义接口
    interface I1 extends I2,I3{//接口和接口之间可以多extends,但是接口不可以extends抽象类,接口不可以implements接口
    	int age = 10;//不可以使用int age;因为默认是final
    	
    	/*I1(){
    		//Interfaces cannot have constructors
    	}*/
    	
    //	定义接口的抽象类
    	void tell2();
    }
    
    interface I2{
    	int age = 20;
    	void tell3();
    }
    
    interface I3{
    	int age = 30;
    	void tell4();
    }
    class P extends Abs1 implements I1,I2,I3{
    //	抽象类可以有构造方法
    	void tell1(String name) {
    		System.out.println("抽象方法被执行...");
    	}
    	public void tell2() {
    		System.out.println("接口1的方法被执行...");
    	}
    	public void tell3() {
    		System.out.println("接口2的方法被执行...");
    	}
    	public void tell4() {
    		System.out.println("接口3的方法被执行...");
    	}
    	@Override
    	void tell1() {
    		System.out.println("抽象方法被执行...");
    	}
    

    这里写图片描述

    抽象类和接口的区别

    这里写图片描述

    多态

    概念

    一个事物的多种表现形态,多种状态.
    1, 方法的重写与重载
    2, 子类对象的多态性 Person p1 = new Man();
    3, 父类的引用指向子类对象

    多态的实现

    向上转型

    • 向上转型,可以调用父类方法也可以调用本类方法
    • 但是父类和子类有相同方法sleep的时候,调用时候会调用子类方法
      向下转型(使用的不多)

    instanceof关键字

    表示运算符前面的这个对象是不是运算符后面的类的实例
    对象 instanceof 类
    只要是本类和本类的父类,都是返回true, 包括Object类

    虚方法的调用

    1, 当子类覆写了父类中的方法,在发生多态的时候,调用的是子类的方法
    2, 通过父类的引用指向子类的对象实体, 当调用方法时, 实际执行的是子类重写父类的方法

    使用多态

    public class TeachTest {
    	public static void main(String[] args) {
    		//实例化一个新的数学老师,
    		//向上转型,可以调用父类方法也可以调用本类方法
    		//但是父类和子类有相同方法sleep的时候,调用时候会调用子类方法
    		Teacher t1 = new MathTeacher();//向上转型
    		t1.teach();
    		t1.sleep();
    		t1.speak();
    		
    		//强制将Teacher 转换为MathTeacher(向下转型)
    		MathTeacher mt = (MathTeacher)t1;
    		mt.teach();
    		//使用封装了的方法
    		EnglishTeacher e = new EnglishTeacher();
    		TeacherAll(e);
    		
    		System.out.println(e instanceof Teacher);
    	}
    	/*
    	         如果要调用类的方法,先实例化一个类,然后分别调用
    	         MathTeacher mt = new MathTeacher();
    	         mt.teach();
    	         mt.sleep();
    	         ChineseTeacher ct = new ChineseTeacher();
    	         ct.teach();
    	         ct.sleep();
    	         发现这样比较麻烦,向上抽取,定义一个新的工具类TeachTest的TeacherAll方法,将方法封装进去
    	         */
    	public static void TeacherAll(Teacher t) {
    		t.sleep();
    		t.teach();
    	}
    }
    
    abstract class Teacher{
    	abstract void teach();
    	void sleep() {
    		System.out.println("老师在睡觉...");
    	}
    	void speak() {
    		System.out.println("老师正在说话...");
    	}
    }
    class MathTeacher extends Teacher{
    	void teach() {
    		System.out.println("数学老师在讲数学...");
    	}
    	void sleep() {
    		System.out.println("数学老师正在躺着睡觉...");
    	}
    }
    class EnglishTeacher extends Teacher{
    	void teach() {
    		System.out.println("英语老师在教英语...");
    	}
    	void sleep() {
    		System.out.println("英语老师睡在沙发上...");
    	}
    }
    

    运行结果:
    这里写图片描述

  • 相关阅读:
    Flink SQL Client初探
    ansible快速部署cassandra3集群
    利用TfidfVectorizer进行中文文本分类(数据集是复旦中文语料)
    spark读取HDFS目录时报错Failed on local exception: com.google.protobuf.InvalidProtocolBufferException
    Spark学习进度-Spark环境搭建&Spark shell
    jquery获取select选中的值
    java零基础到架构师学习线路(附视频教程)
    plsql连接远程oracle数据库
    如何在通用异常处理时获取到方法名称(获取注解参数JoinPoint)
    java:找不到符号(使用lombok)
  • 原文地址:https://www.cnblogs.com/luogg/p/5789006.html
Copyright © 2011-2022 走看看