Java 继承

package com.fish.object;
/*
在现实生活中事物与事物之间是存在关系.
球员---->球队  整体与部分关系   has a 关系  
学生----->人    继承的关系      is a 关系
*/
//球员类
class Player{
    int num; //编码
    String name;
    
    public Player(int num , String name){
        this.num = num;
        this.name = name;
    }
    public void run(){
        System.out.println(name+"开跑...");
    }
}
//球队类
class Team{
    String name;  //球队的名字
    Player p1;  //球员1
     
    Player p2;   //球员2
    Player p3;  //球员3
    
    public  Team(String name,Player p1,Player p2,Player p3){
        this.name = name;
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }
    //开始比赛
    public void startGame(){
        System.out.println(name+"开赛啦!!");
    }
}


class Demo6 
{
    public static void main(String[] args){
        Player p1 = new Player(12,"梅西");
        Player p2 = new Player(7,"C罗");
        Player p3 = new Player(11,"内马尔");
        
        //球队
        Team t = new Team("恒大",p1,p2,p3);
        t.startGame();
        System.out.println("名字:"+ t.p2.name);
    }
}



package com.fish.object;
/*
目前存在的问题:
1. 无法描述清楚这两个类之间的继承关系。
2. 存在着重复代码。
面向对象的三大特征:
1. 封装
2. 继承
3. 多态.
继承:继承是通过关键字extends体现的。
继承的格式:
class 类名1 extends 类名2{
}
继承要注意的事项:
1. 千万不要为了减少重复代码而去继承,只有真正存在着继承关系的时候才去继承。
2. 父类私有的成员不能被继承。
3. 父类的构造函数不能被继承。
4. 创建子类对象时默认会先调用父类无参的构造函数。
*/
//人类 


class Person{
    String name;
    privateint age;
    
    public  Person(String name){
    this.name = name;
    }
    public Person(){
    System.out.println("Person类的构造方法被调用了....");
    }
    public void eat(){
    System.out.println(name+"在吃饭...");
    }
}
//学生类
class Student1 extends Person {  // Student 就称作为Person类的子类, Person类就称作为Student的父类(超类、基类)
    int num; //学号
    
    public Student1(){
        System.out.println("Student类的构造方法被调用了....");
    }
    public void study(){
        System.out.println(name+"good good study , day day up");
    }
}

class Demo7{
    public static void main(String[] args){
        Student1 s = new Student1();
        /*
        s.name = "狗娃";
        System.out.println("名字:"+ s.name);
        s.eat();
        */
    }
}



package com.fish.object;
/*
疑问: 为什么要调用父类的构造方法啊?这样子做的意义在那?
调用父类 的构造方法是可以初始化从父类继承下去的属性的。
*/ 
class Fu1{
    int x = 10;
    String name;
    
    public Fu1(String name){
        this.name = name; 
        System.out.println("Fu类d带参的构造方法...");
    }
    public Fu1(){
        System.out.println("Fu类无参的构造方法...");
    }
}
class Zi1 extends Fu1{
    int x = 20;
    public Zi1(String name){
        super(name); //指定调用父类一个参数的构造函数。
    }
    public void print(){ //子类有两份x,一个是自己的,一个是父亲的
        System.out.println("子类的x= "+ this.x);
        System.out.println("父类的x="+super.x);
    }
}
class Demo8 
{
    public static void main(String[] args) 
    {
        Zi1 z = new Zi1("大头儿子"); 
        System.out.println("name= "+z.name);
        z.print();
    }
}



package com.fish.object;
/*
super关键字:
super关键字代表了父类空间的引用。
super关键字的 作用:
1. 子父类存在着同名的成员时(包括变量和方法),在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员。
2. 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法。通过super调用父类的构造方法时,一定要写在子类的构造方法中
super关键字调用父类构造方法要注意的事项:
1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。
2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句。
3. super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。
super关键字与this关键字的区别:
1. 代表的事物不一致。
1. super关键字代表的是父类空间的引用。
2. this关键字代表的是所属函数的调用者对象。
2. 使用前提不一致。
1. super关键字必须要有继承关系才能使用。
2. this关键字不需要存在继承关系也可使用。
3. 调用构造函数的区别:
1. super关键字是调用父类的构造函数。
2. this关键字是调用本类的构造函数。
*/
class Fu{
    int x = 10;
    String name;
    public Fu(){
        System.out.println("Fu类无参的构造方法..");
    }
    public Fu(String name){
        this.name = name;
        System.out.println("Fu类带参的构造方法..");
    }
    public void eat(){
        System.out.println("小头爸爸吃番薯..");
    }
}

class Zi extends Fu{
    int x = 20; 
    int num;
    
    public Zi(String name,int num){
        super(name); //指定调用了父类带参的 构造方法...
        //this(); // 调用本类无参构造方法..
        //super(); //指定调用了父类无参构造方法。。。
        this.num=num;
        System.out.println("Zi类带参的构造方法.."); 
    }
    public Zi(){
        System.out.println("Zi类无参的构造方法..");
    }
    public void print(){
        System.out.println("x = " +super.x);
    }
    public void eat(){
        System.out.println("大头儿子吃龙虾..");
    }
}
class Demo9 {
    public static void main(String[] args) 
    {
        //Zi z = new Zi("狗娃");
    }
}



package com.fish.object;
/*
目前的问题:父类的功能无法满足子类的需求。
方法重写的前提: 必须要存在继承的关系。
方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。
什么是时候要使用方法的重写:父类的功能无法满足子类的需求时。
方法重写要注意的事项:
1.方法重写时, 方法名与形参列表必须一致。
2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。
3.方法重写时,子类的返回值类型必须要小于或者 等于父类的返回值类型。
4.方法重写时, 子类抛出的异常类型要小于或者等于父类抛出的异常类型。
Exception(最坏)
RuntimeException(小坏)
方法的重载:在一个类中 存在两个或者两个 以上的同名函数,称作为方法重载。
方法重载的要求
1. 函数名要一致。
2. 形参列表不一致(形参的个数或形参 的类型不一致)
3. 与返回值类型无关。
*/
class Animal{  //大的数据 类型 
}

class Fish extends Animal{  //Fish小 的数据类型。
}


class Fu{
    String name;
    public Fu(String name){
        this.name = name;
    }
    public Animal eat() throws RuntimeException {
        System.out.println(name+"吃番薯...");
        return new Animal();
    }
}


class Zi extends Fu{
    String num;
    public Zi(String name){
        super(name);//指定调用 父类带参的构造方法
    }
//重写父类的eat方法
public Animal eat() throws Exception{
    System.out.println("吃点开胃菜..");
    System.out.println("喝点汤....");
    System.out.println("吃点龙虾....");
    System.out.println("吃青菜....");
    System.out.println("喝两杯....");
    System.out.println("吃点甜品....");
    return new Animal();
    }
}
class Demo10{
    public static void main(String[] args) 
    {
        Zi z = new Zi("大头儿子");
        z.eat();
    }
}
package com.fish.object;
/*
需求:使用java描述一下普通的学生、 java基础班的学生、 就业班的学生。
所有的学生都会学习。但是学习的内容不一样。
普通 的学生: 马克思列宁主义。
基础班的学生:学习的是 高等数学。
就业班学生:编程.

*/

//普通的学生类
class Student{
    String name;

    //构造函数
    public Student(String name){
        this.name = name;
    }
    public void study(){
        System.out.println(name+"学习马克思列宁主义");
    }
}
//基础班的学生是属于学生中一种
class BaseStudent extends Student{
    
    public BaseStudent(String name){
        super(name);//指定调用父类构造函数
    }
    //重写
    public void study(){
        System.out.println(name+"学习高等数学..");
    }
}

//就业班学生 也是属于普通学生中一种
class WorkStudent extends Student{
    
    //构造 函数
    public WorkStudent(String name){
        super(name);
    }
    //重写
    public void study(){
        System.out.println(name+"学习编程..");
    }
}
class Demo11 
{
    public static void main(String[] args){
        //System.out.println("Hello World!");
        BaseStudent s = new BaseStudent("李四");
        s.study();
        
        //创建一个就业班的学生
        WorkStudent w = new WorkStudent("张三");
        w.study();
    }
}


package com.fish.object;
/*
instanceof 关键字
instanceof关键字的作用:判断一个对象是否属于指定的类别。
instanceof关键字的使用前提:判断的对象与指定的类别必须要存在继承或者实现的关系。
instanceof关键字的使用格式:
对象  instanceof 类别
instanceof关键字的作用: 目前没用。在多态的场景,非常有用。
一般我们做强制类型转换之前都会使用该关键字先判断一把,然后在进行转换的。
*/


class Animal{
    String name;
    String color;
   
    public Animal(String name, String color){
        this.name = name;
        this.color = color;
    }
}

//狗是属于动物中一种
class Dog extends Animal {
    public Dog(String name,String color){
        super(name,color); //指定调用父类两个 参数的构造函数。
    }
    public void bite(){
        System.out.println(name+"咬人!!");
    }
}

//老鼠 也是属于动物中一种
class Mouse extends  Animal{
    public Mouse(String name,String color){
        super(name,color);
    }
    public void dig(){
        System.out.println(name+"打洞..");
    }
}

class Demo12{
    public static void main(String[] args){
        Dog d = new Dog("哈士奇","白色");
        
        System.out.println("狗是狗类吗?"+ (d instanceof Dog));
        System.out.println("狗是动物类吗?"+ (d instanceof Animal));
        
        //System.out.println("狗是老鼠类吗?"+ (d instanceof Mouse));// false true,报错
        Animal a = new Animal("狗娃","黄色"); //狗娃是人
        System.out.println("动物都是狗吗?"+ (a instanceof Dog));
    }
}



总结:


static(静态、修饰符)

    static修饰成员变量: 如果一个成员变量使用static修饰,那么该成员变量的数据就是一个共享的数据.

静态成员变量的访问方式

    方式一:可以使用对象访问。

        对象.属性名

    方式二:可以使用类名访问。

        类名.属性名

注意: 

1. 非静态成员变量不能使用类名直接访问,要使用对象访问.

2. 千万不要为了访问方便而使用static修饰。一定要数据真正是需要被共享的时候才使用static修饰。


static修饰成员函数:

    静态函数的访问方式

    方式一:可以使用对象访问。

        对象.属性名

    方式二:可以使用类名访问。

        类名.属性名

    推荐使用类名访问静态的成员。

静态函数要注意的细节:

    1. 非静态函数只能由对象调用,静态函数可以由类名或者对象进行调用。

    2. 静态函数中不能直接访问非静态成员,可以直接访问静态的成员。

    3. 非静态函数可以直接访问非静态成员以及可以直接访问静态的成员。

    4. 静态函数中不能出现this或者super关键字。


单例设计模式:保证一个类在内存中只有一个对象。

    饿汉单例设计模式:

        1. 私有化构造函数。

        2. 声明本类的引用类型变量并且指向本类的对象,(private static)

        3. 提供一个公共静态的方法获取本类对象。 

懒汉单例设计模式:

    1. 私有化构造函数。

    2.  声明本类的引用类型变量,但是不要创建对象。

    3. 提供一个公共静态的方法获取本类对象,获取之前先判断是否已经创建了本类的对象,

如果没有创建,创建再返回。如果已经创建了,那么直接访问即可。


继承:

继承的格式:

    class 类名1 extends 类名2{

     }

继承要注意的事项:

    1. 父类私有的成员不能被继承。

    2. 父类的构造函数不能被继承。

    3. 创建子类对象时,默认会先调用父类的无参构造函数,然后再调用子类 的构造函数。


super关键字:super关键字代表的是父类的引用空间。

super关键字的作用:

    1. 如果子父类存在同名的成员时,在子类中默认是访问子类的成员,可以通过super关键字指定访问 父类的成员。

    2. 创建子类对象时,默认会先调用父类的无参构造函数,可以通过super关键字指定调用父类的构造函数,


super关键字要注意的事项:

    1. 如果在子类 的构造函数中没有指定调用具体父类构造函数,那么java编译器会在子类的构造函数上添加super()语句。

    2. super关键字调用构造函数时必须出现构造函数中第一个语句。

    3. this与super调用构造函数的时候不能同时出现在一个构造函数中,因为都需要是第一个语句。


方法重写:子父类存在着同名的函数。

方法重写的需求:如果父类的功能无法满足子类的需求,那么就进行重写。

方法重写的要素:

    1. 函数名与形参列表必须一致。

    2. 子类的权限修饰符必须大于或者等于父类 的权限 修饰符。

    3. 子父类的返回值类型必须小于或者等于父类的返回值类型。

    4. 子类抛出的异常类型必须要小于或者等于父类抛出的异常类型。

instanceof:判断一个对象是否属于某种类型。

instanceof关键字的使用格式:

    对象  instanceof 类。

instanceof的使用前提:判断的对象与类型必须存在继承或者实现的关系。




本文出自 “小鱼的博客” 博客,谢绝转载!

你可能感兴趣的:(ja)