Java学习 11.20

Java接口

1.1练习

有了新的需求:
狗   run    eat
   猫          eat
   马   run

   人   play    feed

   实现功能 并且 优化代码

public abstract class Haha {
   public abstract void eat();
}

public class Dog extends Haha{

   public void eat(){
       System.out.println("肉");
  }

}
public class Cat extends Haha{
   public void eat(){
       System.out.println("鱼");
  }
}
public class People {
   public void feed(Haha  h){
        h.eat();
  }
}
public class JavaTest {

   public static void main(String[] args) {

       Haha  wangcai = new Dog();
       Haha  kate = new Cat();

       People  zhangsan = new People();

       zhangsan.feed(wangcai);
       zhangsan.feed(kate);

  }
}
此时我们创建马类 添加run函数
public class Horse {
   public void run(){
       System.out.println("跑起来");
  }
}
此时人类需要和马类玩耍

public class People {
   public void feed(Haha  h){ h.eat();}
   public void play(){}
}
但是人类的play函数 参数类型不知道写什么,因为人类不仅要和马玩耍 还要和狗玩耍,最主要的是 将来谁有play就能和谁玩耍。按照多态的思想 我们需要给这些有play的类添加一个公共父类 产生多态,从而人类play的时候参数类型写公共父类就可以了。
   
此时我们就需要给 马和狗 找一个公共 父类,但是java中类和类之间的关系是单继承,并且狗已经有父类Haha了 ,而且不能变了(狗的父类Haha是为了和Cat有公共父类产生多态) 马也只能添加父类Haha
   
但是马一旦添加父类Haha 因为Haha是抽象类 有一个抽象函数eat 所以马就必须的实现eat函数 但是我们的需求中马并没有eat函数
 public class Horse extends Haha {
   public void run(){
       System.out.println("跑起来");
  }

   @Override
   public void eat() {
       
  }
}
此时导致的问题就是: 要想优化代码 单继承解决不了问题。不优化又不能体现面向对象思想.

 


1.2 使用接口解决问题


public interface Haha {
   void eat();
}
public interface Hehe {
   void run();
}
public class Cat implements Haha{
   public void eat(){
       System.out.println("鱼");
  }
}
public class Dog implements Haha,Hehe{

   public void eat(){
       System.out.println("肉");
  }

   public void run() {
       System.out.println("跑");
  }
}
public class Horse implements Hehe {
   public void run(){
       System.out.println("跑起来");
  }
}
public class People {
   public void feed(Haha h){
       h.eat();
  }
   public void play(Hehe h){
       h.run();
  }
}

1.3 接口的简介


Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现

Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。
OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层。

1.4 接口的语法规则


1 接口的声明关键字是 interface
 public interface Haha {}

2 接口不能new对象并且也没有构造函数
3 接口中的函数都是抽象的 默认使用public abstract关键字修饰(写不写都是这 并且一般不写)
4 JDK1.8开始有了默认实现函数
public interface Haha {
   void eat();
   default void aaa(){}
}
5 接口中的变量都是公共静态常量 使用 public  static final 修饰 (写不写都是这 并且一般不写)
6 接口和接口之间是继承关系并且是多继承
 public interface Heihei extends Haha,Hehe { }

7 接口和类之间的关系是实现关系并且是多实现
 public class Dog implements Haha,Hehe{   }
8 普通类实现了接口就需要重写接口中的抽象函数    

抽象类 和普通类相比,基本上一样,只有不能new对象并且可以添加抽象函数  
接口只有抽象函数和静态常量

1.5 接口的作用


1 产生接口多态 从而解除程序耦合
2 添加标记
3 定制规则(面向接口编程)

1.6 static关键字


public class JavaTest {
   public static void main(String[] args) {
       Foo  f1 = new Foo();
       f1.id = 666;
       f1.count = 777;

       Foo  f2 = new Foo();

       f2.id = 333;
       f2.count = 444;

       System.out.println(f1.id+"---"+f1.count);
  }
}
public class Foo {

   int  id;
   static  int  count;
   
}
静态变量是多个对象共享的

 

 

 


public class Foo {
  public static   void haha(){
      System.out.println("你好世界");
  }
}

public class JavaTest {
   public static void main(String[] args) {
       Foo.haha();
  }
}

什么时候使用静态的 什么时候使用非静态的。

public class Foo {
  public    void haha(){
      System.out.println("你好世界");
  }
}

public class JavaTest {
   public static void main(String[] args) {
       Foo f1 = new Foo();
       f1.haha();
  }
}

这个地方 都能输出你好世界  此时我们选择使用静态的形式。因为haha是静态函数 直接使用类去调用,所以不需要创建对象,就不需要占据堆区内存。
但是不能理解成 以后所有的函数都要变成静态的,因为有一些函数必须使用对象调用(非静态函数):里面有对应的对象信息
   
先写出非静态 实现功能 再改成静态的     发现还能行 那就使用静态 如果不行了 非静态

1.7 final最终的


A 类  最终类:这个类没有子类也就是说不能被其他类所继承
   
public final class Foo {}
面试题: 请问String类能不能被继承?为什么? 为什么String要设计成final的类?  
public final class String
   implements java.io.Serializable, Comparable<String>, CharSequence {}

什么情景中一个类不允许其他类所继承?
 
B 函数  最终函数:不能被子类重写  

C 成员变量/静态变量  常量:只能赋值一次不能被二次修改了

public final void haha(){

       int  a = 25;
       if(a>15){
           System.out.println("太棒了");
      }

}

代码中出现的  25   15 称之为 魔法值 。这些数字没有语义,所以让代码晦涩难懂
public  class Foo {

   public static  final int  MAX_STUDENT_AGE = 15;

   public void haha(){

       int  a = 25;

       if(a > MAX_STUDENT_AGE){
           System.out.println("太棒了");
      }

  }

}

一次指的是哪一次?
   
 成员的常量    初始化的时候 或者 构造函数
public  class Foo {

   public   final int  MAX_STUDENT_AGE;

   public Foo(){
       MAX_STUDENT_AGE = 777;
  }

}    
 静态的常量    初始化的时候 或者 静态代码块
public  class Foo {

   public static  final int  MAX_STUDENT_AGE;

   /** 静态代码块:这是java中为我们提供的一个初始化数据的代码块 会在类加载到方法区的时候执行一次 */
   static {
       MAX_STUDENT_AGE = 666;
  }
}

静态的常量命名规范:  全大写 下划线命名

 

posted @ 2021-11-20 17:38  吴光熠  阅读(167)  评论(0)    收藏  举报