• day07_继承(上)


    继承概述:

    示例:

    /*
    继承:
    1.提高代码的复用性
    2.让类与类之间产生了关系,有了这个关系,才有了多态的特性
    
    注意:
    千万不要为了获取其他类的功能,简化代码而继承
    必须类与类之间有所属关系才可以继承.
    
     
    在java语言中:java只支持单继承(一个孩纸只有一个父亲),不支持多继承
    
    因为多继承 容易带来安全隐患:当多个父类中定义了
    相同功能,而功能内容不相同,子类对象不能确定运行哪一个
    例如:
    class A
    {
      public void show()
      {
       System.out.println("A");
      }
    }
    class B
    {
      public void show()
      {
       System.out.println("B");
      }
    }
    class C  extends A,B//假设支持多继承
    {
     ...
    }
    C c1=new C()
    c1.show();
    
    java保留这种机制,另一种体现形式完成-->多实现
    
    java支持多层进程: A<—B<—C
    */
    
    关于聚集,聚合和组合:
    
    /*
    聚集:has a 根据事物的紧密联系程度划分:
    聚合:电脑和鼠标
    组合:人的眼睛和人
    */
    
    class Person 
    {
       int age;
       String name;
    }
    class 
    Student
     extends 
    Person
    //不能再继承其它类
    {
       public void study()
        {
          System.out.println("good study");
        }
    }
    class 
    Worker
     extends Person 
    {
    
        public void study()
        {
          System.out.println(
    "good job"
    );
        }
    }
    /*
    如何使用一个继承体系中的功能?
        想要使用体系,先查阅体系父类描述,因为父类中定义的是该体系中 共性功能
        通过了解共性功能,就可以知道体系的基本功能
        那么这个体系已经可以基本使用了
    在具体调用时,要创建最子类的对象.
         A<-B<-C 创建C类对象
       ①有可能父类对象不能创建对象(抽象类,接口)
       ②创建子类对象可以使用更多功能(继承的和自有的)
    
    -->查阅父类功能,创建子类对象使用功能
    */
       子父类出现后,类中成员特点:
    1.变量
    示例:
    /*
    子父类出现后,类成员特点:
    
    类中成员:
    1.变量
    2.函数
    3.构造函数
    
     -->变量
       如果子类中出现非私有的同名成员变量时
      子类访问本类中的变量->this
      子类访问父类中的同名变量-->super
    
    super的使用和this使用几乎一致
    
    this代表的是 本类对象的引用
    super代表的是 父类对象的引用
    
    */
    class Father
    {
        int num=4;
    }
    class Son extends Father//当用到类Son,先加载类Father,再加载Son
    {
         int num=5;
         void show()
        {
         System.out.println(num);//this.num->5
         System.out.println(super.num);//4
         /*
          如果注释掉 int num=5;
          则两者均输出4
          此时父类引用(super)也指向了子类对象new Son();(多态体现)
          堆内存中只有一个num
         */
        }
    }
    class ExtendsDemo
    {
        public static void main(String[] args) 
        {
         Son s=new Son();
         s.show();
        }
    }

    子父变量重名

    子父类变量重名在内存中:

    重名变量在内存

    2.函数
    /*
    2.子父类中的函数
      
      当子类出现和父类一模一样的函数时,
      当子类对象调用该函数,会运行 子类函数的内容
      如同父类的函数被覆盖一样.
    
    这种情况是函数的另一个特性:重写(覆盖)
      注:父类的方法还在内存当中,只不过没有运行而已
    
    覆盖:
    ①子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
    
    ②静态只能覆盖静态.
    
    
    覆盖和重载
    
    重载:函数的参数个数和参数类型不同
    覆盖:子父类方法一模一样(包括返回值类型)
    
    重写一般用在:
    
    当子类继承父类,沿袭了父类的功能,到子类中,
    但是子类虽具备该功能,但是功能的内容却和父类不一致,
    这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义
    并重写功能内容.
    例如:(简单对手机功能拓展)
    class Tel
    {
      void show()
      {
       System.out.println("number");
      }
    }
    class NewTel extends Tel
    {
      void show()
      {
       super.show();
       System.out.println("name");
      }
    }
    */
    class Father
    {
    	 void show()
    	{
    	 System.out.println("Father's show");
    	} 
    }
    class Son extends Father
    { 
    	 void show()
    	{
    	 System.out.println("Son's show");
    	}
    }
    class ExtendsDemo_2
    {
    	public static void main(String[] args) 
    	{
    	 Son s=new Son();
    	 s.show();
    	}
    }

    子父函数重名
     

    3.构造函数

    示例:

    /*
    -->理解为主
    java继承中对构造函数是不继承的,只是调用(隐式或显式)。
    
    子父类的构造函数.
       
       在对子类对象进行初始化时,父类的构造函数也会运行,并且先于子类的构造函数执行
       那是因为子类的构造函数默认第一行有一条隐式语句 super();
    super():
       ①访问父类中的空参数的构造函数.
         子类中所有的构造函数第一行默认都是super();
    
       ②super语句一定定义在子类构造函数的第一行,
       那么在子类构造函数中this语句与super语句二者
       只能存在其一
      
      -->结论:
       ①子类的 所有构造函数,默认都会访问父类中空参数构造函数
         因为隐式super();存在
       
       ②当父类中没有空参数构造函数时,子类必须通过super语句手动指定
          父类中的构造函数
    	
       ③当然,子类的构造函数第一行手动指定this语句来访问本类中的构造函数.
          此时隐式super();不存在.
        但是子类中(一定) 至少会有一个 构造函数会访问父类中的构造函数.
    */
    class  Father //extends Object(所有类的父类)
    {
    	int number;
    	Father()
    	{
          //super();同样存在
    	 number=20;
    	 System.out.println("Father()");
    	
    	}
    	Father(int x)
    	{
    	  System.out.println("Father(int x)");
    	
    	}
    }
    class Son extends Father
    {
    	Son()
    	{
    	  //super();//隐式语句
    
    	  System.out.println("Son()"+"\t"+number);//Son()    20   
    	
    	}
    	Son(int x)
    	{
    	 //super();//依然有
    	 System.out.println("Son(int x)");
    	}
    }
    
    class Extend_Construct
    {
      public static void main(String[] args)
      {
        Son s=new Son();
    	new Son(2);
    	
      }
    }
    
    子父构造函数
    /*
     为什么 子类中的构造函数 要访问 父类中的构造函数??
         因为父类中的数据子类可以直接获取. 
       所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的.
    
      如果要访问父类中指定的构造函数,通过super语句来手动指定
      class Person
    {
      String name;
      Person(String name)
      {
       this.name=name;  
      
      }
    
    }
    class Student extends Person
    {
      Student() 
     {
       super("zhangsan");
      System.out.println(name);//zhangsan
     }
    }
    class Extend_Construct
    {
      public static void main(String[] args)
      {
    	new Student();
      }
    }
    
    */
     
    super()语句为什么要放在第一行?
    示例:
    /*
    为什么super语句要放在第一句?
      子类对象初始化时,如果先初始化自己,在去父类初始化,可能把子类的值覆盖掉
    */
    class Person
    {
      String name;
      Person(String name)
      {
        this.name=name;
        System.out.println(this.name);
    }
    class Student extends Person
    {
     Student(String name) 
     {
      super("lisi");
      this.name=name;
      //super("lisi")如果能成功的话,lisi覆盖掉zhansan从而得不到想要的zhangsan
      System.out.println(this.name);
     }
    }
    class Extend_Construct
    {
      public static void main(String[] args)
      {
    	new Student("zhangsan");
      }
    
    }
    SuperFirst
    final关键字:
    示例:
    /*
    final:最终.作为一个修饰符
    1.可以修饰,函数,变量
    
    2.被final修饰的类不可以被继承
      继承的弊端:打破了封装,例如通过继承重写一些功能
      为了保证封装性,利用final关键字,让一些类不能继承.
    
    3.被 final 修饰的功能不可以被复写(根据需要)
    
    4.被 final 修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,又可以修饰局部变量
      
      当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字.便于
      阅读.而这个值不需要改变,所以加上final修饰.例如:PI=3.1415926
    
    5.内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量
      (当学习到内部类时,在看这一点)
    
    */
    final class Demo//修饰类
    {
       final int x=3;//修饰成员变量
       
       public static final double PI=3.14;//作为常量:所有字母都大写,多个单词下划线连接
                                          //权限够大(public),类名访问/对象之间共享(static),值不会变/常量(final)
       final void show()//修饰成员函数
    	{}
       void show2()
    	{
         final int y=4;//修饰局部变量
        
        }
    
    }  
    class DemoSon extends Demo//编译失败
    {
    }
     


     

     

     
     
  • 相关阅读:
    C语言预处理
    C语言结构体对齐
    C语言共用体、大小端、枚举
    C语言内存分配方法。
    C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
    C语言中函数的传入值与传出值
    #define与typedef在重定义类型中的区别
    宏定义在位运算中的运用
    wait函数
    exit()与_exit()区别
  • 原文地址:https://www.cnblogs.com/yiqiu2324/p/2870862.html
Copyright © 2020-2023  润新知