2021-01-16

本文深入探讨了Java中的面向对象概念,包括构造方法、成员方法、类的初始化过程和static关键字的使用。详细阐述了继承的特性,如单继承、多层继承、构造方法的关系以及super关键字的应用。同时,介绍了多态的概念,强调了其在代码复用和维护性方面的优势。此外,还涉及了抽象类和接口的区别,以及它们在设计上的考量。
摘要由CSDN通过智能技术生成

标题第三周 知识点总结

一.面向对象

1.构造方法
构造方法作用概述
构造方法也是方法:(构造方法格式)

         1)方法名和类名相同
         2)没有具体的返回值类型
          3)连void都没有

作用:
给对象的数据进行初始化----其实为了给类中属性进行赋值! (数据初始化–构造方法初始化)

构造方法注意事项
如果你不提供构造方法,系统会给出默认构造方法
如果你提供了构造方法,系统将不再提供
注意:构造方法也是可以重载的
建议永远给出无参构造方法

//定义一个学生类
class Student{

    //定义一个构造方法
    public  Student(){
        System.out.println("我是学生类的无参构造方法...");
    }

    //成员方法
    public void show(){
        System.out.println("show student") ;
    }

}

//测试类
public class ConstructorTest {

    public static void main(String[] args){
        //创建学生类对象
        Student s = new Student() ;
        s.show();
    }
}

2.类的成员方法
成员方法其实就是我们前面讲过的方法
方法具体划分:
根据返回值
有明确返回值方法
返回void类型的方法
根据形式参数
无参方法和带参方法

//定义一个类
class Code{
    //定义一些成员方法


    //有返回值类型,无参的
    public String show(){
        return "hello,JavaEE" ;
    }

    //又返回值的,带参的
    public String function(int num){
        return "function"+num ;
    }

    //没有返回值,无参的
    public void method(){
        System.out.println("method code...");
    }

    //没有返回值,带参的
    public void function2(String value){
        System.out.println(value);
    }

}


//测试类
public class MethodTest {
    public static void main(String[] args){



        //访问Code类中的这些成员方法
        Code code  = new Code()  ;

       String s =  code.show() ;
        System.out.println(s);

        System.out.println("--------------------------");
       String s2 =   code.function(10);
        System.out.println(s2);

        System.out.println("--------------------------");
        code.method();
        System.out.println("--------------------------");
        code.function2("JavaSe,我来了");

    }
}

3.一个基本类的标准写法

成员变量
构造方法
无参构造方法
带参构造方法
成员方法
getXxx()
setXxx()
给成员变量赋值的方式
无参构造方法+setXxx()
带参构造方法

/**
 *
 * 需求:
 *   猫类 /狗类
 *          属性:
 *                  姓名,年龄,颜色
 *          行为    猫 :
 *                      eat()/sleep()
 *                      playGame() ..
 *
 *   使用面向对象方式:定义一个猫类/狗类,
 *
 *   提供属性私有化,
 *   无参/有参构造方法
 *   自己分析成员方法
 *
 *   在Test3类中进行测试
 *
 */
//狗类
class Dog{

    private String name ;//名字
    private int age ;//年龄
    private String color ;//颜色

    //无参构造
    public Dog() {
    }

    //有参构造方法
    public Dog(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    //公共的访问方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    //狗可以看门
    public void lookDoor(){
        System.out.println("狗看门...");
    }
    public void sleep(){
        System.out.println("狗趴着睡觉...");
    }
}

//测试类
public class Test3 {

    public static void main(String[] args) {

        //方式1:无参构造+setxxx/getXXX方法
        Dog dog = new Dog() ;
        dog.setName("拉布拉多");
        dog.setAge(5) ;
        dog.setColor("棕色");

        System.out.println("狗的种类"+dog.getName()+",年龄是"+dog.getAge()+",颜色是"+dog.getColor());
        dog.lookDoor();
        dog.sleep();

        System.out.println("------------------------------");

        //方式2:通过有参构造方法进行赋值
        Dog dog2 = new Dog("二哈",3,"纯白色");
        System.out.println("狗的种类"+dog2.getName()+",年龄是"+dog2.getAge()+",颜色是"+dog2.getColor());
        dog2.lookDoor();
        dog2.sleep();

    }

}

4.类的初始化过程
Student s = new Student();在内存中做了哪些事情?
加载Student.class文件进内存
在栈内存为s开辟空间
在堆内存为学生对象开辟空间
对学生对象的成员变量进行默认初始化
对学生对象的成员变量进行显示初始化
通过构造方法对学生对象的成员变量赋值
学生对象初始化完毕,把对象地址赋值给s变量
5.static关键字(静态关键字)
可以修饰成员变量和成员方法
1.static关键字特点:
随着类的加载而加载
优先于对象存在
被类的所有对象共享
这也是我们判断是否使用静态关键字的条件
可以通过类名调用

//定义一个Person类
class Person{
    String name ;//姓名
    int age ; // 年龄
//    String country ; //国籍
   static String country ; //国籍  country---被static修饰了---"类变量"

    //提供构造方法:
    public Person(String name,int age,String country){
        this.name = name ;
        this.age = age ;
        this.country = country ;
    }
    //提供两个参数的构造方法
    public Person(String name ,int age){
        this.name = name ;
        this.age = age ;
    }

    //定义一个成员方法:show():显示输出人的基本信息
    public void show(){
        System.out.println("这个人的姓名是"+name+",年龄是"+age+",所在的国籍是"+country);
    }
}

//测试类
public class PersonTest { //----com.qf_05_static.PersonTest.class

    public static void main(String[] args){
        //古代四大美女
        //创建第一个Person
        Person p1 = new Person("西施",23,"中国") ;
        p1.show();

        System.out.println("------------------------------");

//        Person p2 = new Person("貂蝉",18,"中国") ;
        Person p2 = new Person("貂蝉",18) ;
        p2.show();

        System.out.println("------------------------------");

//        Person p3 = new Person("杨玉环",25,"中国");
        Person p3 = new Person("杨玉环",25);
        p3.show();

        System.out.println("------------------------------");

        //Person p4 = new Person("王昭君",24,"中国");
        Person p4 = new Person("王昭君",24);
        p4.show();
        System.out.println("-------------------------------------------------------");
        p1.country ="USA" ;
        p1.show();
        p2.show();
        p3.show();
        p4.show();

    }
}

static关键字注意事项:
在静态方法中是没有this关键字的
静态方法只能访问静态的成员变量和静态的成员方法
1)定义静态的变量----成员位置----成员变量 —加入static
2)非静态的成员方法能不能访问静态的成员变量呢?
既可以访问非静态的成员变量,也可以访问静态的变量!
非静态的成员方法能不能调用静态的成员方法呢?
既可用于调用非静态的成员方法,也可以调用静态的成员方法呢
3)静态的成员方法,能不能访问非静态的成员变量呢?
不能, 只能访问静态的成员变量
静态的成员方法,能不能调用非静态的成员方法呢?
不能,只能调用静态的成员方法
非静态的成员方法,既可以访问静态的成员变量/非静态的成员变量
既可以访问静态的成员方法/非静态的成员方法
静态只能访问静态!

6.静态变量和成员变量(非静态的)的区别:
1)书写格式不同,在类中位置相同的,成员位置(类中,方法外),
静态变量: static修饰 数据类型 变量名;
成员变量 : 数据类型 变量;

2)内存中位置不同:
静态成员变量:方法区中—静态区域中
成员变量:堆内存中
3)生命周期不同 (静态的变量优先于对象存在的)
静态成员变量:随着类的加载而加载, 类就加载一次,static变量加载一次,随着类的加载完毕,在方法区中不会立即消失
成员变量:随着对象的创建而存在, 随着对象的创建完毕,等待垃圾回收器回收!

4)初始化时机不同
静态成员变量:类加载的时候可以直接初始化!
成员变量:对象创建完毕,才进行初始化!
5)调用不同
静态变量可以通过类名调用,也可以通过对象调用
成员变量只能通过对象名调用

二.继承

1. 代码块
在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,
构造代码块,静态代码块,同步代码块(多线程讲解)。
局部代码块
在方法中出现;限定变量生命周期,及早释放,提高内存利用率
构造代码块
在类中方法外出现;
多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块
在类中方法外出现,加了static修饰
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行
一次

//代码块的执行顺序问题
class Code{
    public Code(){
        System.out.println("无参数构造方法");
    }
    public Code(String name){
        System.out.println("有参构造方法");
    }
    {

        System.out.println("构造代码块1");
    }
    static{
        System.out.println("静态代码块");
    }
    {
        System.out.println("构造代码块2");
    }
}

public class Demo {
    static{
        System.out.println("这个世界危在旦夕");
    }
    public static void main(String[] args) {
        System.out.println("95至尊");
        Code c=new Code();
        System.out.println("---------------------------");
        Code c2= new Code("卡雷");

    }
}

2. 继承概述
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属
性和行为,只要继承那个类即可。
通过extends关键字可以实现类与类的继承
继承的案例和继承的好处
通过一个具体案例来演示代码
案例1:学生类和老师。定义两个功能(吃饭,睡觉)
案例2:加入人类后改进。
3.继承的好处
1)提高了代码的复用性
多个类相同的成员可以放到同一个类中
2)提高了代码的维护性
如果功能的代码需要修改,修改一处即可
3)让类与类之间产生了关系,是多态的前提
其实这也是继承的一个弊端:类的耦合性很强
java的设计原则:高内聚低耦合。简单的理解:
内聚就是自己完成某件事情的能力。
耦合就是类与类之间的关系。
我们在设计的时候原则是:自己能完成的就不麻烦别人,这样将来别人产生了修改,就对我的影
响较小。
由此可见:在开发中使用继承其实是在使用一把双刃剑。今天我们还是以继承的好处来使用,因
为继承还有很多其他的特性。
4.Java中的继承特点
继承的特点:
1)仅仅是在Java中,只支持单继承 (类与类之间的关系) class 子类名 extends 父类名{}

      在有的编程语言中,支持多继承  -----   class 子类名 extensd 父类名1,父类名2{...}

 2)虽然Java中类与类之间的关系,不支持多继承,但是可以多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}

: Java中:任何类(自定义的类还是jdk提供的类)都继承自java.lang.Object----代表所有类的父类(超类)

class GrandFather{
    public void method(){
        System.out.println("我是爷爷...");
    }
}
//定义Father类
class Father extends  GrandFather{

    public void show(){
        System.out.println("show father...");
    }
}
//子类
//class Son extends  Father,Mother{ //多继承语言:Java不支持
class Son extends  Father{

    public void playGame(){
        System.out.println("会玩游戏...");
    }
}

//测试类
public class ExtendsDemo2 {
    public static void main(String[] args) {


        //创建子类对象
        Son s = new Son() ;
        s.show();//他父亲的功能
        s.method();//他爷爷的功能

        s.playGame(); //自己的功能
    }
}

5… Java中继承的注意事项
1.子类只能继承父类所有非私有的成员(成员方法和成员变量)私有的成员要访问,间接通过公共访问方法间接访问!
其实这也体现了继承的另一个弊端:打破了封装性
2.子类不能继承父类的构造方法,但是可以通过super(后面讲)关键字去访问父类构造方法。
3.不要为了部分功能而去继承
6.继承中成员变量的关系
继承关系中成员变量的访问问题:
类的成员
成员变量
构造方法
成员方法
继承关系中:
子类继承父类,如果子类中的成员变量名称和父类的成员变量名称不一致的情况,分别访问即可!

  子类继承父类,如果子类中的成员变量名称和父类的成员变量名称一致的情况:
   遵循 "就近原则"

通过下面的案例得出结论:
在子类方法中访问一个变量
首先在子类局部范围找
然后在子类成员范围找
最后在父类成员范围找(肯定不能访问到父类局部范围)
如果还是没有就报错。(不考虑父亲的父亲…)
7.Super关键字
super: 代表的父类的空间标识 (代表父类的对象的地址值引用)
this:代表的本类对象的地址值引用
区别:
this.变量名; 访问的本类的成员变量
super.变量名; 访问的是父类的成员变量

              this.方法名(); 访问的是本类的成员方法
              super.方法名(); 访问的父类的成员方法

              this(): 访问的本类的无参构造
              this(xxx):  访问的是本类的有参构造

              super() :访问的父类的无参构造
              super(xx):访问的父类的有参构造方法
//父类
class Father{



    public Father(String name){
        // super();
        System.out.println("我是父类的有参构造方法...");
    }
}

//子类
class Son extends  Father{

    //提供子类的无参构造方法
    public Son(){
        //显示的访问父类的有参构造方法
        super("随便给") ;
        System.out.println("我是Zi类的无参构造方法...");
    }

    public Son(String name){
       // super("随便给") ;
        this() ; //访问的本类的无参构造方法
        System.out.println("我是Zi类的有参构造方法...");
    }
}

//测试类
public class ExtendsDemo2 {
    public static void main(String[] args) {

        //创建子类对象
        Son s = new Son("hello") ;

    }
}

8.继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法(可以省略不写)
为什么在创建子类对象的时候,为什么要去访问父类的无参构造方法?
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类
数据的初始化。
每一个构造方法的第一条语句默认都是:super()

//父类
class Fu{

    //无参构造
    public Fu(){
        //super() ;
        System.out.println("我是Fu类的无参构造方法...");
    }

    public Fu(String name){
       // super();
        System.out.println("我是父类的有参构造方法...");
    }
}

//子类
class Zi extends  Fu{

    //提供子类的无参构造方法
    public Zi(){
       // super() ;
        System.out.println("我是Zi类的无参构造方法...");
    }
    public Zi(String name){
       // super();
        System.out.println("我是Zi类的有参构造方法...");
    }
}

//测试类
public class ExtendsDemo1 {
    public static void main(String[] args) {

        //测试
        //通过无参创建子类对象
        Zi zi = new Zi() ;
        System.out.println("-------------------");
        Zi zi2 = new Zi("hello") ;
    }
}

三.多态

1. fifinal概述
学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能
随意的继承 API中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java
提供了 fifinal 关键字, 用于修饰不可改变内容。
fifinal:不可改变。可以用于修饰类、方法和变量。
类:被修饰的类,不能被继承。
方法:被修饰的方法,不能被重写
变量:被修饰的变量,不能被重新赋值
final的关键字
“最终的,无法更改的”

有的时候,不想让子类将父类的功能覆盖掉,如何才能保证子类不会将父类的功能覆盖掉?
 *
 *
 * 需求:
 *      有一个父类:Fu
 *              里面有一个show方法, "这里是绝密文件,任何人不得更改!"
 *      定义一个子类,
 *                  重写show方法...   将show方法覆盖了
 *
 *
 *           Java提供了关键字:final,根据具体的情况,可以让子类的功能不会覆盖父类的功能,可以在
 *  父类的成员方法上,加入final修饰 ----"最终的,无法更改的"
 *
 */
class Fu{
   /* public  void show(){
        System.out.println("这里是绝密文件,任何人不得更改!");
    }*/
   public final  void show(){
       System.out.println("这里是绝密文件,任何人不得更改!");
   }
}
//子类
class Zi extends  Fu{

    //方法重写:子类父类覆盖了父类的方法
   /* public void show(){
        System.out.println("这是一堆垃圾...");
    }*/
}

//测试类
public class FinalDemo {
    public static void main(String[] args) {

        Zi z = new Zi() ;
        z.show() ;
    }
}

使用方式
1)final 可以修饰类,该类不能被继承!

final class 类名 {
}
   2)final可以修饰成员方法,该方法不能被重写
修饰符 final 返回值类型 方法名(参数列表){
//方法体
}
   3)final可以修饰成员变量(常量)必须给一个初始化值的,防止类加载完毕,这个变量还没有初始化!
               被fifififinal修饰的常量名称,一般都有书写规范,所有字母都大写。
public class User {
final String USERNAME = "张三";
private int age;
}
    4)而final修饰局部变量的时候,可以先定义,在使用之前必须初始化,而且只能赋值一次!
public class FinalDemo1 {
public static void main(String[] args) {
// 声明变量,使用final修饰
final int a;
// 第一次赋值
a = 10;
// 第二次赋值
a = 20;
// 报错,不可重新赋值
// 声明变量,直接赋值,使用final修饰
final int b = 10;
// 第二次赋值
b = 20; // 报错,不可重新赋值
}
}

final修饰基本数据类型和引用数据类型的区别?
final修饰基本数据类型:
基本数据类型的值不能再改变了!(已经是一个常量了)
final修饰引用数据类型:
引用数据类型的空间地址值不能再改变了!

2. 多态概述
某一个事物,在不同时刻表现出来的不同状态。
举例:
猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。
动物 d = new 猫();
在举一个例子:水在不同时刻的状态
多态前提和体现
1.有继承关系
2.有方法重写
3.有父类引用指向子类对象 ----“向上转型”
3.成员访问特点
访问成员变量
编译看左边,运行看左边
如果编译没有报错,那说明父类的存在这个成员变量,运行的时候使用的父类的变量
访问成员方法
编译看左边,运行看右边
因为存在子类重写了父类的功能,方法重写!
访问静态方法
编译看左边,运行看左边

静态修饰的都和类有关---- 不存在重写,因为类加载的时候,这些静态的功能就已经进入到方法区中
所以前面我说静态方法不能算方法的重写
访问构造方法:
分层初始化:先让父类进行初始化,然后子类初始化

4.多态的好处和弊端
多态的好处
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)

多态的弊端
不能访问子类特有功能
那么我们如何才能访问子类的特有功能呢?
多态中的转型
如何访问子类的功能?
方式1:
子类 对象名 = new 子类名() ;
可以实现的,但是从内存角度考虑,又要创建一个新的对象----堆内存中产生新的空间地址值,内存中资源开销太大了!
多态弊端-------向下转型会出现的问题

关键字:instanceof
对象名 instanceof 引用类型(类) :
判断当前对象名是否为这个数据类型,如果是: 则返回true;否则,false
多态的弊端:不能访问子类的特有功能
为了节省内存空间—使用向下转型 子类型 变量名 = (子类型)父类的引用;

四.抽象类

1.抽象类概述
在Java中,一个没有方法体的方法应该定义为抽象方
法,而类中如果有抽象方法,该类必须定义为抽象类。抽象类可以描述现实世界的事物(概括性的).
2. 抽象类特点
1)抽象类和抽象方法必须用abstract关键字修饰
抽象类:将一个类的成员方法给出一个声明,不给出具体实现,那么这个类必须是抽象类!
抽象方法:跟之前的方法定义是一样,不过在方法声明中 加入一个关键字 abstract,而且这个 方法没有{}, 方法名后面直接是分号结束;
格式
abstract class 类名 {}
public abstract void eat();
2)抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
3)抽象类不能实例化(创建对象)可以按照多态的方式,由具体的子类实例化。-----抽象类多态。
格式: 抽象类 对象名=new 抽象类的子类名
4)抽象类体现的是一种强制子类必须完成的事情:将抽象类中抽象方法,子类必须重写!
3.抽象类的成员特点
1)成员变量
可以是变量
也可以是自定义常量
2)构造方法
可以有无参构造方法/也可以有有参构造方法:目的都得对数据进行初始化!
3)成员方法
可以有抽象方法 限定子类必须完成某些动作
也可以有非抽象方法 提高代码服用性

五.接口

1.对象数组
顾名知义:能够存储对象的数组! (数组可以存储引用数据类型:具体的类)

需求:5个学生(姓名,年龄,性别),5个学生存储数组中,
*          并且将每一个学生的信息遍历出来!
*
*
*          分析:
*              1)学生事物----定义一个学生类
*                      姓名,年龄,性别----属性私有化
*                      提供对外的公共访问方法
*
*              2)创建对象数组---按照格式
*                      数据类型[] 数组名称 = new 数据类型[数组长度] ;
*
*              3)创建5个学生-----
*              4)将这个5个学生存储到数组中
*              5)遍历数组----for循环 通过数组的.length属性:获取长度
*
*
*              数组一般可以存储基本类型,也可以存储引用类型,但是弊端----长度是固定的,不适合长度随时变化的需求!
*
*/

//学生类
public class Student {

    private String name ;
    private int age ;
    private String sex ;

    public Student() {
    }

    public Student(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

//测试类
public class ArrayDemo {


    public static void main(String[] args) {

        //创建对象数组---按照格式
        //数据类型[] 数组名称 = new 数据类型[数组长度] ;
        Student[] students = new Student[5] ;

        //创建5个学生
        Student s1 = new Student("高圆圆",41,"女");
        Student s2 = new Student("张佳宁",30,"女");
        Student s3 = new Student("文章",35,"男");
        Student s4 = new Student("马伊琍",44,"女");
        Student s5 = new Student("姚笛",32,"女");


        //将这个5个学生存储到数组中
        students[0] = s1 ;
        students[1] = s2 ;
        students[2] = s3 ;
        students[3] = s4 ;
        students[4] = s5 ;

        //遍历数组----for循环 通过数组的.length属性:获取长度
        for(int x = 0 ; x < students.length ;x ++){
            //将每个学生都获取到了 students[x]  :学生地址值

            //想通过Student类中getName(),getAge(),getSex():获取学生新
            Student s = students[x] ;//students[0] = s1   //students[1] =s2   ....

            System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getSex());
        }

    }
}

2. 接口概述
继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了,对不。但是,现在有很
多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。而这些额外的动作,并不是
所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的,对不。所以,这些额外的动作
定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。所以,
为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些
猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
什么是接口?
接口是针对某个具体事物提供的一种扩展功能(额外的功能)
3.接口特点
接口用关键字interface表示
格式:interface 接口名 {}
接口名的命名规则:和类名一致: 大驼峰命名法
接口的子实现类实现接口用implements表示
格式:class 类名 implements 接口名 {}
实际开发中: 接口的子实现类的命名规则----- class 接口名+Impl implements 接口名{}
接口的子实现类必须要实现接口中的抽象方法!
接口不能直接实例化----不能直接new 接口名() ;
接口的实例化:通过具体的子实现类进行实例化
接口名 对象名 = new 具体的子实现类名() ; ---------------- 接口多态
接口的子类
要么是抽象类
要么重写接口中的所有抽象方法
接口的子实现类:如果是一个抽象类,那么它一定存在具体的子类,否则接口不能实例化了,否则没有意义!

比抽象类还更抽象一些!
 *  动物类---定义为了抽象类
 *
 *      Cat/Dog 都继承自Animal
 *
 *      特有功能:
 *          猫玩毛线
 *
 *          狗看门
 *      可能一种猫/:可以"做计算","跳高","钻火圈..."----这些功能并不是猫和狗一开始就具备的功能
 *
 *  称为"额外的功能" ----通过后天学习...
 *
 */
//定义一个跳高接口
interface Jump{
    /*public void jumping(){ //接口中的方法不能有方法体--而且方法是抽象方法的

    }*/
    public abstract  void jumping() ;
}


//定义一个跳高猫----实现jumping----->"猫经过学习可以跳高"
//abstract class JumpCat implements  Jump{
 class JumpCat implements  Jump{ //跳高猫是猫一种,只是这个猫它经过后天学习---存在"跳高的功能"

    @Override
    public void jumping() {
        System.out.println("猫经过学习可以跳高");
    }
}





//测试类
public class InterfaceDemo {
    public static void main(String[] args) {


        //创建接口对象
        //Jump jump = new Jump(); 不能实例化

        /**
         * 接口的实例化:通过具体的子实现类进行实例化
         *                     接口名 对象名 = new 具体的子实现类名() ;  接口多态
         */
        Jump jump = new JumpCat() ;
        jump.jumping();

    }
}

4.接口中的成员特点

      成员变量:
              是一个常量---并且存在默认修饰符:
              public static final  可以省略
      成员方法:
              只能是抽象方法----默认修饰符:public abstract : 可以省略


        构造方法:不存在!


        接口也是需要让子实现类必须重写的这些所有抽象方法;
        接口没有构造方法----它只是为了提供额外的功能....
//定义一个接口
interface  Inter{

    //public static final Object obj = new Object() ;  //Jdk提供的Object类  (运行时期常量:jvm--加载Object类)

    public int num = 100 ; // 编译时期常量:只是检查语法,不需要加载的
    public static final int num2 = 200 ;

    void method() ;
    public abstract void show() ;
   // public void show() ;

   /* public Inter(){

    }*/

}
//提供接口的子实现类

class InterImpl implements  Inter{


    @Override
    public void method() {
        System.out.println("method InterImpl...");
    }

    @Override
    public void show() {
        System.out.println("show InterImpl...");
    }
}

//测试类
public class InterfaceDemo2 {
    public static void main(String[] args) {
        //接口多态创建对象
        Inter inter = new InterImpl() ;

        System.out.println(inter.num);//100
        System.out.println(inter.num2);//200
        System.out.println("----------------------------");
//        inter.num = 20 ;  //num 没有final定义,此时变量用final修饰了
        System.out.println(Inter.num2); //static修饰的
        System.out.println(Inter.num);
    }
}

5.抽象类和接口的区别

1)成员的区别

抽象类:
        成员变量: 既可以是常量,也可以是变量
        成员方法:既可以是抽象方法,也可以是非抽象方法
                    抽象方法:必须携带abstract关键字
        构造方法:既可以是有参构造/也可以存在无参构造     ---对数据进行初始化
接口 :
        成员变量:只能是常量:存在默认修饰符:public static final
        成员方法:只能是抽象方法:存在默认修饰符:public abstract
        构造方法:没有构造方法

2)关系的区别

     类与类  :继承关系, extends
           只能单继承,不支持多继承,但是可以多层继承
           类无非:要么具体类/抽象类
     类与接口
               :实现关系, implements
                   一个类继承另一个类的同时,可以实现多个接口
      接口与接口
               :继承关系, extends
               支持单继承,也支持多继承!


3)设计理念的区别:

        抽象类---- 抽象类---子类  由于存在"继承关系",体现一种"is a"的关系
                A类是B类的一种或者B类是A类的一种...

        接口---- 提供的额外的扩展功能(本身事物不存在这个功能,经过后台的学习或者种种,能够获取功能)
        接口和子实现类----存在"实现关系",体现出的一种"like a"的关系
类与类  :继承关系, extends
 *      只能单继承,不支持多继承,但是可以多层继承
 * 类与接口
 *          :实现关系, implements
 *              一个类继承另一个类的同时,可以实现多个接口
 * 接口与接口
 *          :继承关系, extends
 *          支持单继承,也支持多继承!
 *
 */


interface  Inter2{

}
interface  Inter3{

}

//定义一个接口
interface  MyIner extends  Inter2,Inter3{ //接口与接口:可以支持多继承!

}
//任何类都会继承自Object-----所有类的根类(超类)
class InterImpl2  extends  Object implements  Inter2,Inter3{

}



public class InterfaceDemo3 {
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值