继承,多肽,Final关键字

一:继承
1.1
 如何表达这个关系呢?
  通过extends关键字可以实现类与类的继承

  格式:
   class 子类名 extends 父类名 {
   
   }

   父类:基类,超类
   子类:派生类

 需求:
  学生类:
   成员变量:name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx(),eat(),sleep()

  老师类:
   成员变量:name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx(),eat(),sleep() 
   


1.2
 需求:(需要加入方法重写)
  学生类:
   成员变量:name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx(),eat(),sleep()


  老师类:
   成员变量:name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx(),eat(),sleep() 

 按照我们刚才对继承的概述,我们可以找一个父类。
  
  人类:
   成员变量:name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx(),eat(),sleep() 

  学生类:继承人类就可以了。
  老师类:继承人类就可以了。
public class Person {
 //私有化成员变量
 private String name;
 private int age;
 
 //set/get方法
 public void setName(String name){
  this.name = name;
 }
 public String getName(){
  return name;
 }
 public void setAge(int age){
  this.age = age;
 }
 public int getAge(){
  return age;
 }
 
 //有参数和无参数的构造
 public Person(){}
 public Person(String name,int age){
  this.name = name;
  this.age = age;
 }
 
 //吃饭和睡觉的方法
 public void eat(){
  System.out.println("民以食为天");
 }
 
 public void sleep(){
  System.out.println("睡觉也是个大事情");
 }

}
package com.edu_02;

public class Student extends Person{
 //如果父类的方法不满足子类的需求,子类可以写一个一摸一样的方法在自己的类体中,这样就实现了方法重写
 public void eat(){
  System.out.println("学生喜欢吃米饭");
 }
}

package com.edu_02;

public class Teacher extends Person{
 //老师喜欢躺着睡,需要重写父类的sleep()方法
 public void sleep(){
  System.out.println("老师喜欢躺着睡");
 }
 
}

package com.edu_02;

public class Test {
 public static void main(String[] args) {
  //创建一个学生对象
  Student s = new Student();
  s.eat();//子类继承了父类的eat()方法和sleep()方法
  s.sleep();
  
  System.out.println("------------------");
  //创建一个老师对象
  Teacher t = new Teacher();
  t.eat();
  t.sleep();
 }

}

 继承的好处:
  A:提高了代码的复用性
   多个类相同的成员可以放到同一个类中
  B:提高了代码的维护性
   如果功能的代码需要修改,修改一处即可
  C:让类与类之间产生了关系,是多态的前提
  
 方法重写(子类的方法名,参数和父类完全一样,将父类方法覆盖):
 1.必须存在继承关系
 2.父类的方法满足不了你的需求,此时你就需要重写父类的方法,实现自己想要实现的功能

1.3
 继承的特点:(代码演示)
  A:Java只支持单继承,不支持多继承。
  B:Java支持多层(重)继承(继承体系)。
class GrandFather{}

class Father extends GrandFather{}//java不支持多继承,但支持多重继承

class Mother{}
//创建一个儿子类
//class Son extends Father,Mother{}//java中只支持单继承
(不能同时继承father,mother,这俩个类)

 什么时候使用继承呢?
  继承中类之间体现的是:”is a”的关系。

  采用假设法。
   举例:水果,香蕉
   举例:水杯,水果 (不能采用继承。)
   举例:动物,狗 
 (体现的是一种共有的思想)


1.4
 类的组成:
  成员变量
  构造方法
  成员方法

 继承间的成员变量关系:
  A:名字不同,非常简单。
  B:名字相同
   首先在子类局部范围找
   然后在子类成员范围找
   最后在父类成员范围找(肯定不能访问到父类局部范围)
   如果还是没有就报错。(不考虑父亲的父亲…)

   就近原则。

 需求:
  请在show方法中输出40,30,20,10
  
 class Fu {
  public int num = 10; 
 }

 class Zi extends Fu {
  public int num2 = 20;
  public int num = 30; 

  public void show() {
   int num = 40;
   请问这里面代码怎么写???
   
  }
 }

 class ExtendsDemo5 {
  public static void main(String[] args) {
   Zi z  = new Zi();
   z.show();
  }
 }
class Fu {
 public int num = 10;
 public int num4 = 50;
}

class Zi extends Fu {
 public int num2 = 20;
 public int num = 30; 

 public void show() {
  int num = 40;
  //请问这里面代码怎么写???
  System.out.println(num);//输出40
  System.out.println(this.num);//this代表的是本类的一个对象,谁调用我,我指代谁
  System.out.println(num2);
  System.out.println(super.num);//super可以理解为父类的一个对象
  System.out.println(num4);
 }
}

public class ExtendsDemo2 {
 public static void main(String[] args) {
  //创建Zi类的对象
  Zi z = new Zi();
  z.show();
  
 }

}


 怎么去访问父亲的成员呢?
  java就提供了一个关键字:super

 super:
  super代表父类存储空间的标识(可以理解为父类对象)

 this和super的使用区别?
  A:成员变量
   this.成员变量 本类的成员变量
   super.成员变量 父类的成员变量
  B:成员方法
   this.成员方法() 本类的成员方法
   super.成员方法()父类的成员方法 

 
1.5
 继承间的成员方法关系:
  A:方法名不同,非常简单
  B:方法名相同
   首先在子类中找
   然后在父类中找
   如果还是没有就报错。(不考虑父亲的父亲…)
class Fu2{
 
 public void show(){
  System.out.println("fu2中的show方法");
 }
 
 public void method(){
  System.out.println("fu2的method方法");
 }
 
 private void function(){
  System.out.println("fu2的function方法");
 }
 
}

class Zi2 extends Fu2{
 public void show(){
  System.out.println("zi2中的show方法");
 }
 
 public void sleep(){
  System.out.println("睡觉的方法");
 }
 
}


public class ExtendsDemo4 {
 public static void main(String[] args) {
  //创建zi2的对象
  Zi2 z = new Zi2();
  z.sleep();
  z.show();
  z.method();
  //z.fuction();//子类无法继承父类中私有的方法
 }

}

   
1.7
 继承间构造方法的关系:
  子类中所有的构造方法默认都会访问父类中空参数的构造方法(super())

 为什么呢?
  因为子类会继承父类中的数据,可能还会使用父类的数据。
  所以,子类初始化之前,一定要先完成父类数据的初始化。
  每个子类的构造方法的第一行,有一条默认的语句:
   super();

  注意:仅仅是完成数据的初始化,创建对象目前必须用new申请空间。
 
 假如父类没有无参构造方法,该怎么办呢?
  A:调用父类的其他构造方法。带参构造。
   怎么访问呢?
    super(...)

 注意:
  super(…)或者this(….)必须出现在第一条语句上。
  因为如果可以放后面的话,就会对父类的数据进程多次初始化。所以,只能放在第一条语句上。

 建议:
  永远给出无参构造方法。
 
1.6
 猫狗案例继承版
  猫:
   成员变量:type,name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx()
       show()
  狗:
   成员变量:type,name,age
   构造方法:无参,带参
   成员方法:getXxx()/setXxx()
       show()

  提取出动物类,完成代码,并测试。

  DongWu -- Animal
  gou  -- Dog
  mao  -- Cat
package com.edu_05;

public class Animal {
 private String type;
 private int age;
 private String name;
 
 public Animal(){}
 public Animal(String name,String type,int age){
  this.name = name;
  this.type = type;
  this.age = age;
 }
 
 public void setType(String type){
  this.type = type;
 }
 public String getType(){
  return type;
 }
 
 public void setName(String name){
  this.name = name;
 }
 public String getName(){
  return name;
 }
 
 public void setAge(int age){
  this.age  =age;
 }
 public int getAge(){
  return age;
 }
 
 //吃饭的方法
 public void eat(){
  System.out.println("动物喜欢吃粮食");
 }
 
}
package com.edu_05;

public class Cat extends Animal{
 public Cat(){}
 public Cat(String name,String type,int age){
  setAge(age);
  setName(name);
  setType(type);
 }
 
 //猫喜欢吃鱼
/* public void eat(){
  System.out.println("猫咪喜欢吃鱼");
 }
*/
}
package com.edu_05;

public class Dog extends Animal{
 //有参数和无参数的构造方法
 public Dog(){}
 public Dog(String name,String type,int age){
  setAge(age);
  setName(name);
  setType(type);
 }
 
 //狗喜欢吃肉
 public void eat(){
  System.out.println("狗喜欢吃肉");
 }

}
package com.edu_05;

public class Test {
 public static void main(String[] args) {
  //创建对象
  Dog d = new Dog();
  d.eat();
  
  System.out.println("------------");
  Cat c = new Cat("bob", "波斯猫", 2);
  c.eat();
  System.out.println(c.getAge()+"  "+c.getName()+"  "+c.getType());
  
 }

}

1.7 水果案例继承版
  苹果:
   成员变量:品种,颜色,价格
   构造方法:有参无参
   成员方法:getXxx()/setXxx();
     show()
     
  橘子:
   成员变量:品种,颜色,价格
   构造方法:有参无参
   成员方法:getXxx()/setXxx();
     show()
     
  提取水果类,完成代码,并测试
 
package com.edu_06;

public class Fruit {
 private String type;
 private String color;
 
 public Fruit(){}
 public Fruit(String type,String color){}

 public void setType(String type){
  this.type = type;
 }
 public String getType(){
  return type;
 }
 
 public void setColor(String color){
  this.color = color;
 }
 public String getColor(){
  return color;
 }
 
 public void show(){
  System.out.println(type+"  "+color+"  ");
 }
}
package com.edu_06;

public class Apple extends Fruit{
 
 //有参和无参构造
 public Apple(){}
 public Apple(String type,String color){
  setColor(color);
  setType(type);
 }

}
package com.edu_06;

public class Test {
 public static void main(String[] args) {
  //创建Apple对象
  Apple a = new Apple();
  a.show();
  
  System.out.println("-------------");
  Apple a2 = new Apple("红富士", "红色");
  a2.show();
  System.out.println(a2.getColor()+"  "+a2.getType());
  
 }

}

二:final关键字
 在实际开发的时候,有些方法的内容一旦写定后,就不允许被改动。
 即时是子类,也不允许。那么该怎么解决这个问题呢?
  java为了解决这样的问题就提供了一个关键字:final

 final:
  最终的意思。它可以修饰类,方法,变量。

 特点:
  修饰方法,方法不能被重写。
  修饰类,类不能被继承。
  修饰变量,变量的值不能再改动。其实这个时候变量已经变成了常量。

 常量:
  A:字面值常量
   'a',12,"hello"
  B:自定义常量
   就是把变量用final修饰。

   定义一个常量。

   final 数据类型 变量名;
class Fu{//一个类如果被final修饰过后,就不能被继承
 //写一个被final修饰的方法
 public final void eat(){
  System.out.println("fu的eat()");
 }
}

class Zi extends Fu{
 //尝试重写父类中的eat(),子类无发重写父类中被final修饰过的方法
 /*public void eat(){
  
 }*/
 final int NUM = 20;
 
 //自定义一个常量,这个常量有多个单词组成
 final int MAX_AGE = 30;
 
 final String URL = "WWW.BAIDU.COM";
 
}


public class FinalDemo {
 public static void main(String[] args) {
  //创建Zi的对象,访问他的被final修饰过的成员变量num
  Zi z = new Zi();
  //尝试改变被final修饰过的成员变量num
  //z.num = 30;//被final修饰过的变量不能被更改,此时他已经成了常量
  System.out.println(z.NUM);
  
 }

}

三:多态
 3.1
 多态:同一个对象,在不同时刻表现出来的不同状态。

 举例:
  A:猫
   猫是猫
   猫是动物
  B:水
   水(液态)
   冰(固态)
   水蒸气(气态)

 多态的前提:
  A:有继承关系 
  B:有方法重写(不是必要条件,但是只有有了方法重写多态才有意义) 
  C:有父类引用指向子类对象

   Fu f = new Fu();

   左边:Fu类型的引用
   右边:Fu类型的对象

   Zi z = new Zi();

   Fu f = new Zi(); 
 
3.2
 成员访问特点
  A:成员变量
   编译看左边,运行看左边
  B:构造方法
   子类构造默认访问父类的无参构造
  C:成员方法(重点理解)
   编译看左边,运行看右边

   为什么变量和方法不一样呢?
    方法重写。
  D:静态成员方法
   编译看左边,运行看左边
   因为静态的内容是和类相关的,与对象无关。 
练习:
看程序写结果(先判断有没有问题,如果没有,写出结果)
class Fu {
 public void show() {
  System.out.println("fu show");
 }
}

class Zi extends Fu {
 public void show() {
  System.out.println("zi show");
 }

 public void method() {
  System.out.println("zi method");
 }
}

class DuoTaiTest {
 public static void main(String[] args) {
  Fu f = new Zi();
  f.method();
  f.show();
 }

 代码示例:
class Fu{
 //创建一个成员变量
 int num = 20;
 public void show(){
  System.out.println("fu的show()");
 }
 
 public static void method(){
  System.out.println("fu的method()");
 }
}

class Zi extends Fu{//1.存在继承关系
 int num = 30;
 public void show(){//2.存在方法重写
  System.out.println("zi的show");
 }
 
 public static void method(){
  System.out.println("zi的method()");
 }
}


public class DuoTaiDemo {
 public static void main(String[] args) {
  //3.父类引用指向子类对象
  Fu f = new Zi();
  System.out.println(f.num);
  //多态的情况下:成员变量的访问特点是,编译看左边,运行看左边
  
  System.out.println("---------------------------");
  f.show();
  //多态的情况下:成员方法的访问特点:编译看左边,运行看右边
  System.out.println("---------------------------");
  
  f.method();
  //多态情况下静态成员方法的访问特点:编译看左边,运行看左边
  
  
 }

}

练习:(猫狗案例演示)
 如何使用子类特有功能
  A:创建子类对象
  B:把父类引用转为子类对象

 向上转型
  从子到父
  父类引用指向子类对象

 向下转型
  从父到子
  父类引用转为子类对象 
 
package com.edu_09;

public class Animal {
 private String type;
 private int age;
 private String name;
 
 public Animal(){}
 public Animal(String name,String type,int age){
  this.name = name;
  this.type = type;
  this.age = age;
 }
 public void setName(String name){
  this.name = name;
 }
 public String getName(){
  return name;
 }
 public void setAge(int age){
  this.age  = age;
 }
 public int getAage(){
  return age;
 }
 public void setType(String type){
  this.type = type;
 }
 public String getType(){
  return type;
 }
 
 //吃的方法
 public void eat(){
  System.out.println("动物喜欢吃饭");
 }
 
}
package com.edu_09;

public class Cat extends Animal{

 public Cat(){}
 public Cat(String name,String type,int age){
  setAge(age);
  setName(name);
  setType(type);
 }
 
 //猫喜欢池鱼
 public void eat(){
  System.out.println("猫喜欢吃鱼");
 }
 
 //猫有一个特有的功能,猫会捉老鼠
 public void catchMouce(){
  System.out.println("猫有一个捉老鼠的特有技能");
 }
 
}
package com.edu_09;

public class Dog extends Animal{
 public Dog(){}
 public Dog(String name,int age,String type){
  setAge(age);
  setName(name);
  setType(type);
 }
 
 //狗有一个特有技能会看门
 public void lookDoor(){
  System.out.println("狗会看门");
 }
 
}
public class Test {
 public static void main(String[] args) {
  //使用多态的方式创建一个Cat对象
  Animal a = new Cat();
  a.eat();
  //a.catchMouce();
  //需求:就像在这里调用猫中特有功能,捉老鼠
  //方式1:创建Cat对象,使用Cat类型去接受
  Cat c = new Cat();
  c.catchMouce();
  System.out.println("------------");
  
  //方式2:向下转型,将父类引用转换成子类对象
  Cat c2 = (Cat)a;
  c2.catchMouce();
  
  System.out.println("--------------");
  //将a这个引用转换成Dog对象???
  //Dog d = (Dog)a;
  //java.lang.ClassCastException:类型转换异常
  //d.eat();
  //d.lookDoor();
  
  System.out.println("----------------");
  Animal a2 = new Dog();
  a2.eat();
  //a2.lookDoor();
  Dog d = (Dog)a2;
  d.lookDoor();
 }

}

 
四:抽象类
 4.1
 抽象类特点:
  A:抽象类和抽象方法必须用abstract关键字修饰
  B:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
  C:抽象类不能实例化
   那么,如果实例化并使用呢?
   按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
  D:抽象类的子类
   要么是抽象类
   要么重写抽象类中的所有抽象方法

 抽象类的作用:
  强制要求子类必须要重写某些方法。 
 
 
abstract class Animal{
 //抽象类中不一定有抽象方法
 public void sleep(){
  System.out.println("动物都喜欢睡大觉");
 }
 
 //定义一个抽象方法,1.使用abstract进行修饰  2,抽象方法没有方法体,因为抽象根本就不是一个具体的方法
 //3.如果一个类中有抽象方法,这个类一定是抽象类  4.抽象方法没有具体的实现,需要让他的具体子类做具体的实现
 public abstract void eat();
}

class Dog extends Animal{
 @Override
 public void eat() {
  System.out.println("狗喜欢吃肉");
 }
}

class Cat extends Animal{
 @Override
 public void eat() {
  System.out.println("猫喜欢吃鱼");
 }
 
}

//定义一个抽象类继承Animal这个类,如果一个抽象类继承另一个抽象类,不需要重写父类中的抽象方法
//abstract class Person extends Animal{}


public class AbstractDemo {
 public static void main(String[] args) {
  //创建狗的对象
  Dog d = new Dog();
  d.eat();
  
  System.out.println("----------");
  //使用多态的方式创建对象,并调用eat()方法
  //此时使用的多态的方式是:抽象类多态
  /**
   * 多态的分类:
   * 1.普通类多态
   * 2.抽象类多态
   *   前两种全部是父类引用指向子类对象
   * 3.接口多态
   *   父接口引用指向接口实现类对象
   */
  Animal a = new Dog();
  a.eat();
 }

}

 4.2
 抽象类 -- 特点 -- 成员特点 -- 案例

 类的组成:
  成员变量:
  构造方法:
  成员方法:

 抽象类的成员:
  成员变量:可以是变量,也可以是常量。
  构造方法:有构造方法
   不能实例化,构造方法有什么用呢?
   用于子类访问父类数据的初始化。
  成员方法:既可以是抽象的,也可以是非抽象的。
 
abstract class Animal2{
 //成员变量:可以是变量,也可以是常量。
 int num = 10;//变量
 final int num2 = 20;
 
 //抽象类有构造方法吗???
 //既然我们刚才说过我们的抽象类不能被实例化,为什么抽象类还可以具有构造方法呢?
 //这里的构造方法是为了初始化我们的父类数据,并不是用来做一个对象的实例化的
 public Animal2(){}
 
 //成员方法:可以是普通成员方法,也可以是抽象方法,
 //一个类如果具有抽象方法这个类一定是抽象类
 
}



 4.3 抽象类练习
 以后我们在写代码的时候,有这样的分析过程。
 
 分析:
  从具体到抽象。
 
 实现:
  从抽象到具体。

 使用:
  使用具体的类。

 猫:
  成员变量:
   name,age,type
  构造方法:
   有参无参
  成员方法;
   getXxx()/setXxx()
   eat(),catchMouse()

 狗:
  成员变量:
   name,age,type
  构造方法:
   有参无参
  成员方法;
   getXxx()/setXxx()
   eat(),lookDoor()
   
 发现有共性的内容,所以我们就提取出一个父类出来:
 
 动物:抽象类
  成员变量:
   name,age,type
  构造方法:
   有参无参
  成员方法;
   getXxx()/setXxx()
   eat()---抽象的

 猫:
  继承自动物

  构造方法:
   
 狗:
  继承自动物

  构造方法:
 
package com.edu_11;

public abstract class Animal {
 private String type;
 private String name;
 
 public Animal(){}
 public Animal(String type,String name){
  this.name = name;
  this.type = type;
 }
 
 public void setType(String type){
  this.type = type;
 }
 public String getType(){
  return type;
 }
 public void setName(String name){
  this.name = name;
 }
 public String getName(){
  return name;
 }
 
 //吃饭的抽象方法
 public abstract void eat();
}
package com.edu_11;

public class Cat extends Animal{
 public Cat(){}
 public Cat(String name,String type){
  setName(name);
  setType(type);
 }

 @Override
 public void eat() {
  System.out.println("猫爱吃鱼");
 }
 
 //猫会捉老鼠
 public void catchMouse(){
  System.out.println("猫会逮老鼠");
 }

}
  
package com.edu_11;

public class Dog extends Animal{
 
 public Dog(){}
 public Dog(String name,String type){
  setName(name);
  setType(type);
 }

 @Override
 public void eat() {
  System.out.println("狗爱吃肉");
 }
 
 //狗特有的看门方法
 public void lookDoor(){
  System.out.println("狗会看门");
 }

}
package com.edu_11;

public class Test {
 public static void main(String[] args) {
  //利用多态的方式创建一个狗的对象
  Animal a = new Dog();
  a.eat();
  Dog d = (Dog)a;
  d.lookDoor();
  
  System.out.println("--------------");
  //使用猫的有参构造创建一个对象
  Animal a2 = new Cat("bob", "加菲猫");
  a2.eat();
  System.out.println(a2.getName()+"  "+a2.getType());
  
 }

}


 多态:
  具体类多态
   class Fu {}
   class Zi extends Fu {}
  抽象类多态
   abstract class Fu {}
   class Zi extends Fu {}
  接口多态

 多态的前提:
  继承
  方法重写
   因为抽象类中的方法是抽象方法。
  父类引用指向子类对象
 
作业分析(上课做简单分析,下课代码自己实现):
 老师案例
  具体事物:基础班老师,就业班老师
  共性:姓名,年龄,讲课。

 自己分析自己写

 基础班老师:
  成员变量:姓名,年龄
  构造方法:无参,带参
  成员方法:getXxx()/setXxx()
      show()
      讲课()
 就业班老师:
  成员变量:姓名,年龄
  构造方法:无参,带参
  成员方法:getXxx()/setXxx()
      show()
      讲课()

 老师:抽象类
  成员变量:姓名,年龄
  构造方法:无参,带参
  成员方法:getXxx()/setXxx()
      show()
      讲课() 抽象方法

 基础班老师:
  构造方法:无参,带参
  成员方法:讲课() 抽象方法

 就业班老师:
  构造方法:无参,带参
  成员方法:讲课() 抽象方法
package com.edu10;

public abstract class Person {
 private String name;
 private int age;
 public Person(){}
 public Person(String name,int age){
  this.name=name;
  this.age=age;
 }
 public void setName(String name){
  this.name=name;
 }
 public String getName(){
  return name;
 }
 public void setAge(int age){
  this.age=age;
 }
 public int getAge(){
  return age;
 }
 public abstract void show();
}
package com.edu10;

public class BasicTeacher extends Person{
 public BasicTeacher (){}
 public BasicTeacher(String name,int age){
  setAge(age);
  setName(name);
 }
 public void show(){
  System.out.println("老师讲的是基础课");
 }
 

}
package com.edu10;

public class JobTeacher extends Person{
 public JobTeacher(){}
 public JobTeacher(String name,int age){
  setAge(age);
  setName(name);
 }
 public void show(){
  System.out.println("老师是就业班老师");
 }
 

}
package com.edu10;

public class Test {
 public static void main(String[] args) {
  Person p=new BasicTeacher();
  p.show();
    Person p1=new JobTeacher("马老师",20);
    p1.show();
    System.out.println(p1.getName()+" "+p1.getAge());
 }

}

 
 
五:接口 
5.1 认识接口:不是我们现实生活中的usb接口等等实物的接口,类实现接口代表着这个类自身功能的一种扩展,
    所以接口代表着一种扩展的能力

5.2
 接口的特点:
  A:定义接口要用关键字interface表示
   格式:interface 接口名 {}
  B:类实现接口用implements表示 
   格式:class 类名 implements 接口名 {}
  C:接口不能实例化
   那么,接口如何实例化呢?
   按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
  D:接口的实现类
   要么是抽象类
   要么重写接口中的所有抽象方法

 多态的前提:
  A:有继承或者实现关系
  B:有方法重写
  C:有父类引用或者父接口引用指向子类或者实现类对象

 多态分类:
  A:具体类多态
  B:抽象类多态
  C:接口多态 
 
interface inter{
 //接口中可以定义那些东西呢?
 
 //1.在接口中定义一些变量
 //接口中所有的变量都会默认被final修饰,所以我们的接口中说白了只能定义常量,不能定义变量
 //接口中的成员变量不仅被final默认修饰,还被static默认修饰
 //我们接口中的变量全部是静态常量
 public static final int num = 20;
 
 //2.接口中能否定义一个构造方法呢??
 //接口中不能存在构造方法
 //public inter(){}
 
 
 //3.接口中可以存在普通的成员方法吗?
 //接口中的所有方法都是抽象方法
 public abstract void show();
}

//定义一个类实现这个接口
class InterImpl implements inter{
 @Override
 public void show() {
  System.out.println("来自接口中扩展的抽象方法");
 } 
}

//定义一个抽象类,让这个抽象类实现接口,此时这个抽象类不需要重写接口中的抽象方法
abstract class AbstractInterImpl implements inter{}


public class InterfaceDemo {
 public static void main(String[] args) {
  //利用多态的方式将接口进行实例化
  inter i = new InterImpl();
  //试图更改成员变量的值
  //i.num = 30;//接口中所有的变量都会默认被final修饰,所以我们的接口中说白了只能定义常量,不能定义变量
  //System.out.println(i.num);
  System.out.println(inter.num);
    }
}


5.3 
 接口的成员特点:
  A:成员变量
   只能是常量。
   默认修饰符:public static final
  B:构造方法
   没有构造方法
  C:成员方法
   只能是抽象方法。
   默认修饰符:public abstract
 
5.4 
 类与类:
  继承关系。只能单继承,可以多层(重)继承。
 
 类与接口:
  实现关系。可以单实现,也可以多实现。
  还可以在继承一个类的同时实现多个接口。



 接口与接口:
  继承关系。可以单继承,也可以多继承。

5.5
 接口和抽象类的关系最后分析:
 抽象类和接口的区别
  A:成员区别
   抽象类:
    成员变量:可以是变量,也可以是常量
    构造方法:有构造方法
    成员方法:可以是抽象方法,也可以是非抽象方法
   接口:
    成员变量:只能是常量。默认修饰符 public static final
    成员方法:只能是抽象方法。默认修饰符 public abstract
  B:关系区别
   类与类:
    继承关系。只能单继承,可以多层(重)继承。
 
   类与接口:
    实现关系。可以单实现,也可以多实现。
    还可以在继承一个类的同时实现多个接口。

   接口与接口:
    继承关系。可以单继承,也可以多继承。
  C:设计理念区别
   抽象类被继承体现的是:"is a"的关系。抽象类定义的是共性功能。
   接口被实现体现的是:"like a"的关系。接口定义的是扩展功能。 
 
interface Inter1{}

interface Inter2{}

interface Inter3 extends Inter2,Inter1{}

//创建一个类实现一个接口,或者多个接口
class InterImpl3 implements Inter1,Inter2{}

//一个类还可以在继承一个类的同时实现多个接口
class InterImpl4 extends InterImpl3 implements Inter3{}


5.6
继承,抽象类,接口代码综合演练
 分析:从具体到抽象
 实现:从抽象到具体
 使用:使用具体类

 猫狗案例,加入跳高的额外功能

 猫:
  成员变量:
   name,age
  构造方法:
   无参,带参
  成员方法:
   getXxx()/setXxx()
   show()
   catchMouse()
   eat()

 跳高猫:继承自猫
  成员方法:
   跳高

 狗:
  成员变量:
   name,age
  构造方法:
   无参,带参
  成员方法:
   getXxx()/setXxx()
   show()
   lookDoor()
   eat()

 跳高狗:继承自狗
  成员方法:
   跳高

 无论猫还是狗,都是动物,所以我们提取出一个动物类:

 跳高接口:
  跳高

 动物类:抽象类
  成员变量:
   name,age
  构造方法:
   无参,带参
  成员方法:
   getXxx()/setXxx()
   show(){}
   eat(); 抽象方法

 猫:继承自动物
  构造方法:
   无参,带参
  成员方法:
   catchMouse()
   eat()

 跳高猫:继承自猫,实现跳高接口
  构造方法:
   无参,带参
  成员方法:
   跳高

 狗:继承自动物
  构造方法:
   无参,带参
  成员方法:
   lookDoor()
   eat()

 跳高狗:继承自狗,实现跳高接口
  构造方法:
   无参,带参
  成员方法:
   跳高 
 
package com.edu_13;

public abstract class Animal {
 //私有化成员变量
 private String name;
 private int age;
 
 //有参无参构造
 public Animal(){}
 public Animal(String name,int age){
  this.name = name;
  this.age = age;
 }
 
 public void setName(String name){
  this.name = name;
 }
 public String getName(){
  return name;
 }
 
 public void setAge(int age){
  this.age = age;
 }
 public int getAge(){
  return age;
 }
 
 //吃的抽象方法
 public abstract void eat();
}

package com.edu_13;

public class Cat extends Animal{
 
 public Cat(){}
 public Cat(String name,int age){
  setAge(age);
  setName(name);
 }

 @Override
 public void eat() {
  System.out.println("猫爱吃鱼");
 }
 
 //所有的猫都会逮老鼠
 public void catchMouse(){
  System.out.println("猫会逮老鼠");
 }

}
package com.edu_13;

public class Dog extends Animal{
 
 //有参无参构造
 public Dog(){}
 public Dog(String name,int age){
  setAge(age);
  setName(name);
 }

 @Override
 public void eat() {
  System.out.println("狗吃骨头");
 }
 
 //所有的狗都会看门
 public void lookDoor(){
  System.out.println("狗会看家");
 }
}
package com.edu_13;

public interface Inter {
 public abstract void jump();
}
package com.edu_13;

public class JumpCat extends Cat implements Inter{
 
 public JumpCat(){}
 public JumpCat(String name,int age){
  setAge(age);
  setName(name);
 }

 @Override
 public void jump() {
  System.out.println("经过多年的刻苦训练,终于练成了跳高技能");
 }

}
package com.edu_13;

public class JumpDog extends Dog implements Inter{
 
 public JumpDog(){}
 public JumpDog(String name,int age){
  setAge(age);
  setName(name);
 }

 @Override
 public void jump() {
  System.out.println("这条狗不简单呐,居然会跳高");
 }

}

package com.edu_13;

public class Test {
 public static void main(String[] args) {
  //多态的方式创建一个普通狗
  Animal a = new Dog();
  a.eat();
  Dog d = (Dog)a;
  d.lookDoor();
  System.out.println("------------------");
  //创建一个跳高狗
  JumpDog jd = new JumpDog();
  jd.eat();
  jd.lookDoor();
  jd.jump();
 }

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值