JavaJava学习笔记

面向对象04

2018-11-15  本文已影响17人  丫甘九

final关键字的引入

final 最终的意思。常见的他可以修饰类、方法、变量
package miangxiangduixaing04;

public class fu {
    public final void show(){
        System.out.println("这里是绝密的,任何人都不能改");
    }

}


package miangxiangduixaing04;

public class zi extends fu {
/*public void show(){
    System.out.println("这是一堆垃圾");
    //报错,子中的show无法覆盖父中的show
}*/
    public  void show1(){
        System.out.println("这是一个不同于show方法的show1方法");
    }
}


package miangxiangduixaing04;

public class zidemo {
    public static void main(String[] args) {
        zi z = new zi();
        z.show();//因为子类中的方法重写,导致了父类中的方法内容被改变
        /*由于继承中方法有一个现象      方法重写,导致了父类中的方法被子类覆盖
         * 有些时候,我们不想让子类覆盖掉父类中的功能,只能让他使用
         * 针对这种情况,java就提供了一个关键字       final*/
        z.show1();
    }

}

结果为:
这里是绝密的,任何人都不能改
这是一个不同于show方法的show1方法



final修饰类、方法、变量的特点

final可以修饰类、方法、变量
特点
常量
package miangxiangduixaing04;

/*public final class fu1 {
    public void show(){
        System.out.println("123");
    }

}
1
*/
/*public class fu1{
    public final void show(){
        System.out.println("这是final修饰的show方法");
    }
}
2*/
public class fu1{
    int num = 10;
    public final int num2 = 20;
    
}

package miangxiangduixaing04;

/*public class zi1 extends fu1 {

}
error  父类为final类,不能被继承
1
*/
/*public class zi1 extends fu1 {
public void show(){
    System.out.println("这是一个public的show方法");
}
}
error 报错,因为父方法为final修饰,不能被重写
2
*/
public class zi1 extends fu1 {
public void show(){
    int num = 100;
    System.out.println(num);
    int num2 = 200;
    System.out.println(num2);
}

}

package miangxiangduixaing04;

public class zidemo1 {
    public static void main(String[] args) {
        zi1 z = new zi1();
        z.show();
    }

}

结果为:
100
200


按理说被final修饰的变量不可以在赋值了,为什么这还能打出200????不懂

final关键字修饰局部变量

package miangxiangduixaing04;

public class student {
int age = 18;
}


public class studenttest {
public static void main(String[] args) {
    int x = 10;
    System.out.println(x);
    final int y = 20;
    System.out.println(y);
    System.out.println("--------------------");
    student s = new student();
    System.out.println(s.age);
    s.age=100;
    System.out.println(s.age);
    System.out.println("--------------------");
    final student  ss = new student();
    System.out.println(ss.age);
    ss.age=200;
    System.out.println(ss.age);
    
}
}
结果为:
10
20
--------------------
18
100
--------------------
18
200

final关键字面试题

基本类型:是值不能被改变
引用类型:是地址值不能被改变

final修饰变量的初始化时机

多态的概述和前提条件

多态概述
多态前提和体现
多态中成员访问特点

A 成员变量
编译看左边,运行看左边
(fu f(左) = new zi(右)())
B 构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
C 成员方法
编译看左边,运行看右边
D 静态方法
编译看左边,运行看左边
注:变量没有重写,但是方法可以被覆盖,父类方法被子类覆盖掉了

package mianxiangduixiang04;

public class fu {
    public int  num = 10;
public void show() {
    System.out.println("show fu");
}
public static void function() {
    System.out.println("function fu");
}

}


package mianxiangduixiang04;

public class zi extends fu {
    public int num2 = 20;
    public int num = 100;
public void show() {
    System.out.println("show zi");
}
public void method() {
    System.out.println("show method");
}
public static void function() {
    System.out.println("function zi");
}
}


package mianxiangduixiang04;

public class futest {
    public static void main(String[] args) {
        fu f = new zi();
        f.show();
        System.out.println("-----------------");
        System.out.println(f.num);
        /*System.out.println(f.num2);error
         * 因为父类中没有num2,编译看左边,运行看左边*/
        System.out.println("------------------");
        /*f.method();error  因为父类中没有method方法*/
        f.function();
    }

}
结果为:
show zi
-----------------
10
------------------
function fu

多态的好处

多态的好处
多态的弊端

多态中向上转型和向下转型

多态的弊端:
不能使用子类的特有功能
那我就想使用子类的特有功能行不行

那怎么用呢?
A 创造子类对象调用方法即可
(可以,但是很多时候不合理,并且,太占内存了)
B 把父类的引用强制转换为子类的引用(向下转型)
对象间的转型问题
向上转型:
fu f = new zi()
向下转型:
zi z = (zi)f //要求该f是必须能转换成子的

package miangxiangduixaing04;

public class fu3 {
public void show(){
    System.out.println("show fu");
}
}


package miangxiangduixaing04;

public class zi3 extends fu3 {
public void show(){
    System.out.println("show zi");
}
public void method(){
    System.out.println("method");
}
}


package miangxiangduixaing04;

public class fu3test {
    public static void main(String[] args) {
        fu3 f = new zi3();
        f.show();
        //f.method();error  编译看左边,运行看右边
        //创建子类对象
        zi3 z = new zi3();
        z.show();
        z.method();
        //你能把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
        //如果可以,但是如下
        zi3 z1 = (zi)f;//引用不能new,不然就是创造一个对象出来了,
        f本身就是zi,所以才能引用
        zi.show();
        zi.method();
    }

}

结果为:
show zi
show zi
method
(后面俩报错)
多态中的转型问题

抽象类的引入

抽象类概述

回想前面的猫狗案例,提取出了一个动物类,并且我们在前面也创建过了动物对象,其实这是不对的,为什么呢?因为我说动物,你能知道我说的是什么动物么?只有看到了具体的动物,你才知道这是什么动物,所以说,动物本身并不是一个具体的事物,而是一个抽象的事物,只有具体的猫狗才是具体的动物,同理,不同的动物吃的也不一样,我们不应该在动物类中给出一个具体体现,而是给出一个声明即可,在java中,一个没有方法体的方法应该定义为抽象方法,该类必须定义为抽象类
注:
什么是没有方法体的方法
没有方法体是直类似接口的写法,没有代码的方法也是有方法体的。可以举个例子: 没有方法体:public abstract void noMethodBody(); 空方法体:public void empertyBody(){} 是有本质的区别的。没有方法体的方法,是需要你去实现的。空方法体,是需要覆盖的

抽象类的特点

抽象类的特点
package miangxiangduixaing04;

public abstract class animal {
    //抽象方法
    //抽象方法不能有主体,就是加了abstract的方法不能有大括号
public abstract void eat();//没有方法体
/*public void eat() { }//空方法体*/
public animal(){
    
}

}

package miangxiangduixaing04;

/*public class dog extends animal {

}
error 因为父类是抽象类,所以子类必须是抽象类,否则就会报错*/
public class dog extends animal{//不报错,因为这子类是抽象类
    public void eat(){
        //不报错,因为这重写了父类的抽象方法
        System.out.println("ment");
    }
}

package miangxiangduixaing04;

public class animaltest {
    public static void main(String[] args) {
        /*animal a = new animal();error 因为抽象类是不能实例化的*/
        animal a  = new dog();
        a.eat();
    }

}

抽象类的成员特点

抽象类的成员特点

-成员变量:既可以是变量,也可以是常量

package mianxiangduixiang04;

abstract class animal {
    public int num = 10;
    public final int num2 = 100;
    public animal() {}//无参构造
    public animal(String name,int age) {}//带参构造
    public abstract void show();
    public void method() {
        System.out.println("method");
    }

}


package mianxiangduixiang04;

public class dog extends animal {
public void show() {
    System.out.println("show dog");
}
}


package mianxiangduixiang04;

public class animaltest {
    public static void main(String[] args) {
        animal a = new dog();
        a.num = 1;
        System.out.println(a.num);
        /*a.num2 = 20;error ,因为num2是常量,只能赋值一次*/
        System.out.println(a.num2);
        System.out.println("----------------");
        a.show();
        a.method();
    }

}

结果为:
1
100
----------------
show dog
method

接口概述

回到我们讲过的猫狗案例,我们就想想,狗一般就是看门的,猫一般就是作为宠物,但是呢,现在有很多狗会钻火圈,猫会跳绳,而这些额外的动作并不是一开始就具备的,这应该属于经过特殊培训后的特殊动作,显然,这些定义到动物类中不合适,也不合适直接定义到猫类或者狗类中,因为只有部分的猫狗具备这些动作,所以,为了体现事物功能的扩展性,java就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这部分额外的功能实现即可

接口特点
package mianxiangduixiang04;
interface animaltrain{//接口   是抽象的,无法实例化
    public void jump();
    
}
/*abstract  class dogtrain implements animaltrain{//抽象类实现接口

}*/
public class dogtrain implements animaltrain{
    public void jump() {
        System.out.println("狗可以跳高了");
    }
}

package mianxiangduixiang04;

public class animaltraintest {
public static void main(String[] args) {
    /*animaltrain a = new animaltrain();
    a.jump();*/
    animaltrain a = new dogtrain();
    a.jump();
}
}

结果为:
狗可以跳高了

*自我理解:为什么要有封装?为什么要有继承?为什么要有多态?为什么要有接口?

接口的成员特点
成员变量
构造方法
成员方法
package mianxiangduixiang04;
interface  inter{
    public int  num = 10;
    public  int num2 = 20;
    /*public inter () {}error 没有构造方法*/
    public void show() ;//接口方法不能带主体,说明接口方法是抽象的
}
//接口名+Impl这种格式是实现接口类格式
public class interImpl implements inter{
    public interImpl() {
        super();
    }
//所有类都继承自Object类,所以super访问的是Object类
    public void show() {}
}


package mianxiangduixiang04;

public class interinpltest {
public static void main(String[] args) {
    inter i = new interImpl();
    System.out.println(i.num);
    System.out.println(i.num2);
    /*i.num=100;
    i.num2=200;
    System.out.println(i.num);
    System.out.println(i.num2);error 无法为最终变量分配值*/
}
}

类与类,类与接口,接口与接口的关系

package mianxiangduixiang04;
interface father{
    public abstract void show();
}
interface mother {
    public abstract void show2();
}
interface sister extends father,mother{
    public abstract void show3();
}
public class son extends Object implements father,mother{
    //继承一个类的同时实现多个接口
    public void show() {
        System.out.println("show son");
    }
    public void show2() {
        System.out.println("show2 son");
    }

}


package mianxiangduixiang04;

public class fathertest {
    public static void main(String[] args) {
        father f = new son();
        f.show();
        /*f.show2();error*/
        mother m = new son();
        /*m.show();error*/
        m.show2();
        //对应的接口只能调对应的方法
    }

}
 结果为:
show son
show2 son

抽象类和接口的区别

成员区别
关系区别
设计理念区别
上一篇 下一篇

猜你喜欢

热点阅读