No_16_0229 Java基础学习第九天

文档版本开发工具测试平台工程名字日期作者备注
V1.02016.02.29lutianfeinone


final 关键字

  • final关键字,可以修饰成员变量成员方法

  • 特点:

    • 修饰的,类不能被继承
    • 修饰的变量,变量就变成了常量,只能被赋值一次
    • 修饰的方法,方法不能被重写
  • final关键字面试题

  • Eg1: final修饰局部变量

    • 在方法内部,该变量不可以被改变
    • 在方法声明上,分为基本类型引用类型作为参数的情况
      • 基本类型,是值不能被改变
      • 引用类型,是地址值不能被改变,但是该对象堆内存的值可以改变。
  • Eg2: final修饰变量的初始化时机

    • 对象构造完毕前即可
 
 
  1. class Student {
  2. int age = 10;
  3. }
  4. class FinalTest {
  5. public static void main(String[] args) {
  6. //局部变量是基本数据类型
  7. int x = 10;
  8. x = 100;
  9. System.out.println(x);
  10. final int y = 10;
  11. //无法为最终变量y分配值
  12. //y = 100;
  13. System.out.println(y);
  14. System.out.println("--------------");
  15. //局部变量是引用数据类型
  16. Student s = new Student();
  17. System.out.println(s.age);
  18. s.age = 100;
  19. System.out.println(s.age);
  20. System.out.println("--------------");
  21. final Student ss = new Student();
  22. System.out.println(ss.age);
  23. ss.age = 100;
  24. System.out.println(ss.age);
  25. //重新分配内存空间
  26. //无法为最终变量ss分配值
  27. ss = new Student();
  28. }
  29. }

多态

多态概述
  • 某一个事物,在不同时刻表现出来的不同状态。
    • 举例:
      • 猫可以是猫的类型。猫 m = new 猫();
      • 同时猫也是动物的一种,也可以把猫称为动物。
        • 动物 d = new 猫();
      • 再举一个例子:水在不同时刻的状态
  • 多态前提和体现
    • 继承关系
    • 方法重写
    • 父类引用指向子类对象
      • Fu f = new Zi();
多态的分类:
  • 具体类多态:
    • class Fu{}
    • class Zi extends Fu{}
    • Fu f = new Zi();
  • 抽象类多态:
    • abstract class Fu{}
    • class Zi extends Fu{}
    • Fu f = new Zi();
  • 接口多态:
    • interface Fu{}
    • class Zi implements Fu{}
    • Fu f = new Zi();
多态中的成员访问特点:
  • A:成员变量:编译看左边,运行看左边

  • B:构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化

  • C:成员方法: 编译看左边,运行看右边。由于成员方法存在方法重写,所以它运行看右边。

  • D:静态方法:编译看左边,运行看左边。

    • (静态和类相关,算不上重写,所以,访问还是左边的)
 
 
  1. /*
  2. 多态:同一个对象(事物),在不同时刻体现出来的不同状态。
  3. 举例:
  4. 猫是猫,猫是动物。
  5. 水(液体,固体,气态)。
  6. 多态的前提:
  7. A:要有继承关系。
  8. B:要有方法重写。
  9. 其实没有也是可以的,但是如果没有这个就没有意义。
  10. 动物 d = new 猫();
  11. d.show();
  12. 动物 d = new 狗();
  13. d.show();
  14. C:要有父类引用指向子类对象。
  15. 父 f = new 子();
  16. */
  17. class Fu {
  18. public int num = 100;
  19. public void show() {
  20. System.out.println("show Fu");
  21. }
  22. public static void function() {
  23. System.out.println("function Fu");
  24. }
  25. }
  26. class Zi extends Fu {
  27. public int num = 1000;
  28. public int num2 = 200;
  29. public void show() {
  30. System.out.println("show Zi");
  31. }
  32. public void method() {
  33. System.out.println("method zi");
  34. }
  35. public static void function() {
  36. System.out.println("function Zi");
  37. }
  38. }
  39. class DuoTaiDemo {
  40. public static void main(String[] args) {
  41. //要有父类引用指向子类对象。
  42. //父 f = new 子();
  43. Fu f = new Zi();
  44. System.out.println(f.num);
  45. //找不到符号
  46. //System.out.println(f.num2);
  47. f.show();
  48. //找不到符号
  49. //f.method();
  50. f.function();
  51. }
  52. }
  53. /*
  54. * 运行结果:
  55. 100
  56. show Zi
  57. function Fu
  58. */


多态的优缺点
  • 多态的好处
    • 提高了程序的维护性(由继承保证)
    • 提高了程序的扩展性(由多态保证)
  • 多态的弊端

    • 父类不能访问子类特有功能
  • 如何才能访问子类的特有功能呢?

    • 创建子类对象,调用方法即可。(然而很多时候不合理,且太占内存)
    • 向下转型:把父类的引用强制转换为子类的引用。
      • Zi z = (Zi)f; //要求该f必须是能够转换为Zi的
  • 现象: 子可以当做父使用,父不能当作子使用。
多态中的转型问题
  • 向上转型
    • 从子到父
    • 父类引用指向子类对象
  • 向下转型

    • 从父到子
    • 父类引用转为子类对象
  • 孔子装爹案例

 
 
  1. //多态的问题理解:
  2. class 孔子爹 {
  3. public int age = 40;
  4. public void teach() {
  5. System.out.println("讲解JavaSE");
  6. }
  7. }
  8. class 孔子 extends 孔子爹 {
  9. public int age = 20;
  10. public void teach() {
  11. System.out.println("讲解论语");
  12. }
  13. public void playGame() {
  14. System.out.println("英雄联盟");
  15. }
  16. }
  17. //Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了
  18. //但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢?
  19. //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹
  20. //向上转型
  21. 孔子爹 k = new 孔子();
  22. //到人家那里去了
  23. System.out.println(k爹.age); //40
  24. k爹.teach(); //讲解论语
  25. //k爹.playGame(); //这是儿子才能做的,一做就报错!
  26. //讲完了,下班回家了
  27. //脱下爹的装备,换上自己的装备
  28. //向下转型
  29. 孔子 k = (孔子) k爹;
  30. System.out.println(k.age); //20
  31. k.teach(); //讲解论语
  32. k.playGame(); //英雄联盟

  • 多态中的对象变化内存图


  • 多态练习:猫狗案例
 
 
  1. class Animal {
  2. public void eat(){
  3. System.out.println("吃饭");
  4. }
  5. }
  6. class Dog extends Animal {
  7. public void eat() {
  8. System.out.println("狗吃肉");
  9. }
  10. public void lookDoor() {
  11. System.out.println("狗看门");
  12. }
  13. }
  14. class Cat extends Animal {
  15. public void eat() {
  16. System.out.println("猫吃鱼");
  17. }
  18. public void playGame() {
  19. System.out.println("猫捉迷藏");
  20. }
  21. }
  22. class DuoTaiTest {
  23. public static void main(String[] args) {
  24. //定义为狗
  25. Animal a = new Dog();
  26. a.eat();
  27. System.out.println("--------------");
  28. //还原成狗
  29. Dog d = (Dog)a;
  30. d.eat();
  31. d.lookDoor();
  32. System.out.println("--------------");
  33. //变成猫
  34. a = new Cat();
  35. a.eat();
  36. System.out.println("--------------");
  37. //还原成猫
  38. Cat c = (Cat)a;
  39. c.eat();
  40. c.playGame();
  41. System.out.println("--------------");
  42. }
  43. }


  • 不同地方饮食文化不同的案例
 
 
  1. class Person {
  2. public void eat() {
  3. System.out.println("吃饭");
  4. }
  5. }
  6. class SouthPerson extends Person {
  7. public void eat() {
  8. System.out.println("炒菜,吃米饭");
  9. }
  10. public void jingShang() {
  11. System.out.println("经商");
  12. }
  13. }
  14. class NorthPerson extends Person {
  15. public void eat() {
  16. System.out.println("炖菜,吃馒头");
  17. }
  18. public void yanJiu() {
  19. System.out.println("研究");
  20. }
  21. }
  22. class DuoTaiTest2 {
  23. public static void main(String[] args) {
  24. //测试
  25. //南方人
  26. Person p = new SouthPerson();
  27. p.eat();
  28. System.out.println("-------------");
  29. SouthPerson sp = (SouthPerson)p;
  30. sp.eat();
  31. sp.jingShang();
  32. System.out.println("-------------");
  33. //北方人
  34. p = new NorthPerson();
  35. p.eat();
  36. System.out.println("-------------");
  37. NorthPerson np = (NorthPerson)p;
  38. np.eat();
  39. np.yanJiu();
  40. }
  41. }
  42. /*
  43. 运行结果:
  44. 炒菜,吃米饭
  45. -------------
  46. 炒菜,吃米饭
  47. 经商
  48. -------------
  49. 炖菜,吃馒头
  50. -------------
  51. 炖菜,吃馒头
  52. 研究
  53. */


多态中继承练习
  • 继承的时候:

    • 子类中有和父类中一样的方法,叫重写
    • 子类中没有父亲中出现过的方法,方法就被继承过来了。
  • Eg:(不太理解)

 
 
  1. /*
  2. 多态的成员访问特点:
  3. 方法:编译看左边,运行看右边。
  4. 继承的时候:
  5. 子类中有和父类中一样的方法,叫重写。
  6. 子类中没有父亲中出现过的方法,方法就被继承过来了。
  7. */
  8. class A {
  9. public void show() {
  10. show2();
  11. }
  12. public void show2() {
  13. System.out.println("我");
  14. }
  15. }
  16. class B extends A {
  17. /*
  18. public void show() {
  19. show2();
  20. }
  21. */
  22. public void show2() {
  23. System.out.println("爱");
  24. }
  25. }
  26. class C extends B {
  27. public void show() {
  28. super.show();
  29. }
  30. public void show2() {
  31. System.out.println("你");
  32. }
  33. }
  34. public class DuoTaiTest4 {
  35. public static void main(String[] args) {
  36. A a = new B();
  37. a.show();
  38. B b = new C();
  39. b.show();
  40. }
  41. }
  42. // 运行结果:
  43. //爱
  44. //你


抽象类

抽象类概述
  • 动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。在Java中,一个没有方法体(连大括号也没有)的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
抽象类特点
  • 抽象类抽象方法必须用abstract关键字修饰
    • 格式
      • abstract class 类名 {}
      • public abstract void eat();
  • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
  • 抽象类不能实例化(抽象类如何实例化呢?)
    • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    • 抽象类有构造方法,其作用是为了用于子类访问父类数据的初始化
  • 抽象类的子类
    • 要么是抽象类
    • 要么重写抽象类中的所有抽象方法
 
 
  1. //abstract class Animal //抽象类的声明格式
  2. abstract class Animal {
  3. //抽象方法
  4. //public abstract void eat(){} //空方法体,这个会报错。抽象方法不能有主体
  5. public abstract void eat();
  6. public Animal(){}
  7. }
  8. //子类是抽象类
  9. abstract class Dog extends Animal {}
  10. //子类是具体类,重写抽象方法
  11. class Cat extends Animal {
  12. public void eat() {
  13. System.out.println("猫吃鱼");
  14. }
  15. }
  16. class AbstractDemo {
  17. public static void main(String[] args) {
  18. //创建对象
  19. //Animal是抽象的; 无法实例化
  20. //Animal a = new Animal();
  21. //通过多态的方式
  22. Animal a = new Cat();
  23. a.eat();
  24. }
  25. }


抽象类的成员特点
  • 成员变量
    • 可以是变量
    • 也可以是常量
  • 构造方法
    • 有构造方法,但是不能实例化
    • 那么,构造方法的作用是什么呢?
      • 用于子类访问父类数据的初始化
  • 成员方法

    • 可以有抽象方法 作用:限定子类必须完成某些动作
    • 也可以有非抽象方法 提高代码复用性
  • 抽象定义类练习:

 
 
  1. //定义抽象的动物类
  2. abstract class Animal {
  3. //姓名
  4. private String name;
  5. //年龄
  6. private int age;
  7. public Animal() {}
  8. public Animal(String name,int age) {
  9. this.name = name;
  10. this.age = age;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public int getAge() {
  19. return age;
  20. }
  21. public void setAge(int age) {
  22. this.age = age;
  23. }
  24. //定义一个抽象方法
  25. public abstract void eat();
  26. }
  27. //定义具体的狗类
  28. class Dog extends Animal {
  29. public Dog() {}
  30. public Dog(String name,int age) {
  31. super(name,age); //重要知识点!!!
  32. }
  33. public void eat() {
  34. System.out.println("狗吃肉");
  35. }
  36. }
  37. //定义具体的猫类
  38. class Cat extends Animal {
  39. public Cat() {}
  40. public Cat(String name,int age) {
  41. super(name,age);
  42. }
  43. public void eat() {
  44. System.out.println("猫吃鱼");
  45. }
  46. }
  47. //测试类
  48. class AbstractTest {
  49. public static void main(String[] args) {
  50. //测试狗类
  51. //具体类用法
  52. //方式1:
  53. Dog d = new Dog();
  54. d.setName("旺财");
  55. d.setAge(3);
  56. System.out.println(d.getName()+"---"+d.getAge());
  57. d.eat();
  58. //方式2:
  59. Dog d2 = new Dog("旺财",3);
  60. System.out.println(d2.getName()+"---"+d2.getAge());
  61. d2.eat();
  62. System.out.println("---------------------------");
  63. Animal a = new Dog();
  64. a.setName("旺财");
  65. a.setAge(3);
  66. System.out.println(a.getName()+"---"+a.getAge());
  67. a.eat();
  68. Animal a2 = new Dog("旺财",3);
  69. System.out.println(a2.getName()+"---"+a2.getAge());
  70. a2.eat();
  71. //练习:测试猫类
  72. }
  73. }


  • 抽象教师类练习:
 
 
  1. //定义抽象的老师类
  2. abstract class Teacher {
  3. //姓名
  4. private String name;
  5. //年龄
  6. private int age;
  7. public Teacher() {}
  8. public Teacher(String name,int age) {
  9. this.name = name;
  10. this.age = age;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public int getAge() {
  19. return age;
  20. }
  21. public void setAge(int age) {
  22. this.age = age;
  23. }
  24. //抽象方法
  25. public abstract void teach();
  26. }
  27. //基础班老师类
  28. class BasicTeacher extends Teacher {
  29. public BasicTeacher(){}
  30. public BasicTeacher(String name,int age) {
  31. super(name,age);
  32. }
  33. public void teach() {
  34. System.out.println("基础班老师讲解JavaSE");
  35. }
  36. }
  37. //就业班老师类
  38. class WorkTeacher extends Teacher {
  39. public WorkTeacher(){}
  40. public WorkTeacher(String name,int age) {
  41. super(name,age);
  42. }
  43. public void teach() {
  44. System.out.println("就业班老师讲解JavaEE");
  45. }
  46. }
  47. class AbstractTest2 {
  48. public static void main(String[] args) {
  49. //具体的类测试,自己玩
  50. //测试(多态)
  51. //基础班老师
  52. Teacher t = new BasicTeacher();
  53. t.setName("刘意");
  54. t.setAge(30);
  55. System.out.println(t.getName()+"---"+t.getAge());
  56. t.teach();
  57. System.out.println("--------------");
  58. t = new BasicTeacher("刘意",30);
  59. System.out.println(t.getName()+"---"+t.getAge());
  60. t.teach();
  61. System.out.println("--------------");
  62. //就业班老师
  63. t = new WorkTeacher();
  64. t.setName("林青霞");
  65. t.setAge(27);
  66. System.out.println(t.getName()+"---"+t.getAge());
  67. t.teach();
  68. System.out.println("--------------");
  69. t = new WorkTeacher("林青霞",27);
  70. System.out.println(t.getName()+"---"+t.getAge());
  71. t.teach();
  72. }
  73. }


抽象类的几个小问题
  • 一个类如果没有抽象方法,可以定义为抽象类?如果可以,有什么意义?
    • 可以
    • 禁止创建对象
  • abstract不能和哪些关键字共存
    • private 冲突
    • final 冲突
    • static 无意义(通过类名直接访问没有内容的方法体)

接口

接口概述
  • 狗一般就是看门,猫一般就是作为宠物。但是,现在有很多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。而这些额外的动作,并不是所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的。所以,这些额外的动作定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。
    所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
接口特点
  • 接口用关键字interface表示
    • 格式:interface 接口名 {}
  • 类实现接口用implements表示
    • 格式:class 类名 implements 接口名 {}
  • 接口不能实例化(接口如何实例化呢?)
    • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。
  • 接口的实现类(子类):

    • 抽象类:实现接口,但意义不大
    • 具体类:重写接口中的所有抽象方法
  • 补充:多态的三种形式

    • 具体类多态(几乎没有)
    • 抽象类多态(常用)
    • 接口类多态(最常用 )
接口成员特点
  • 成员变量
    • 只能是常量
    • 默认修饰符 public static final
  • 构造方法
    • 没有,因为接口主要是扩展功能的,而没有具体存在。
    • 所有的类都默认继承自一个类:Object。(类Object 是类层次结构的根类。每个类都使用Object作为超类)
  • 成员方法
    • 只能是抽象方法
    • 默认修饰符 public abstract

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

  • 类与类
    • 继承关系,只能单继承,但是可以多层继承
  • 类与接口
    • 实现关系
      • 可以单实现,也可以多实现
      • 还可以在继承一个类的同时实现多个接口。
  • 接口与接口
    • 继承关系,可以单继承,也可以多继承

抽象类和接口的区别

  • 成员区别
    • 抽象类
      • 成员变量:变量,常量;
      • 构造方法:可以有
      • 成员方法:可以是抽象方法,也可以是非抽象方法;
    • 接口
      • 成员变量:只可以是常量;
      • 构造方法:没有
      • 成员方法:只能是抽象方法
  • 关系区别
    • 类与类 继承,单继承
    • 类与接口 实现,单实现,多实现
    • 接口与接口 继承,单继承,多继承
  • 设计理念区别

    • 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能
    • 接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能
  • 跳高猫练习:

 
 
  1. /*
  2. 猫狗案例,加入跳高的额外功能
  3. 分析:从具体到抽象
  4. 猫:
  5. 姓名,年龄
  6. 吃饭,睡觉
  7. 狗:
  8. 姓名,年龄
  9. 吃饭,睡觉
  10. 由于有共性功能,所以,我们抽取出一个父类:
  11. 动物:
  12. 姓名,年龄
  13. 吃饭();
  14. 睡觉(){}
  15. 猫:继承自动物
  16. 狗:继承自动物
  17. 跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口
  18. 接口:
  19. 跳高
  20. 部分猫:实现跳高
  21. 部分狗:实现跳高
  22. 实现;
  23. 从抽象到具体
  24. 使用:
  25. 使用具体类
  26. */
  27. //定义跳高接口
  28. interface Jumpping {
  29. //跳高功能
  30. public abstract void jump();
  31. }
  32. //定义抽象类
  33. abstract class Animal {
  34. //姓名
  35. private String name;
  36. //年龄
  37. private int age;
  38. public Animal() {}
  39. public Animal(String name,int age) {
  40. this.name = name;
  41. this.age = age;
  42. }
  43. public String getName() {
  44. return name;
  45. }
  46. public void setName(String name) {
  47. this.name = name;
  48. }
  49. public int getAge() {
  50. return age;
  51. }
  52. public void setAge(int age) {
  53. this.age = age;
  54. }
  55. //吃饭();
  56. public abstract void eat();
  57. //睡觉(){}
  58. public void sleep() {
  59. System.out.println("睡觉觉了");
  60. }
  61. }
  62. //具体猫类
  63. class Cat extends Animal {
  64. public Cat(){}
  65. public Cat(String name,int age) {
  66. super(name,age);
  67. }
  68. public void eat() {
  69. System.out.println("猫吃鱼");
  70. }
  71. }
  72. //具体狗类
  73. class Dog extends Animal {
  74. public Dog(){}
  75. public Dog(String name,int age) {
  76. super(name,age);
  77. }
  78. public void eat() {
  79. System.out.println("狗吃肉");
  80. }
  81. }
  82. //有跳高功能的猫
  83. class JumpCat extends Cat implements Jumpping {
  84. public JumpCat() {}
  85. public JumpCat(String name,int age) {
  86. super(name,age);
  87. }
  88. public void jump() {
  89. System.out.println("跳高猫");
  90. }
  91. }
  92. //有跳高功能的狗
  93. class JumpDog extends Dog implements Jumpping {
  94. public JumpDog() {}
  95. public JumpDog(String name,int age) {
  96. super(name,age);
  97. }
  98. public void jump() {
  99. System.out.println("跳高狗");
  100. }
  101. }
  102. class InterfaceTest {
  103. public static void main(String[] args) {
  104. //定义跳高猫并测试
  105. JumpCat jc = new JumpCat();
  106. jc.setName("哆啦A梦");
  107. jc.setAge(3);
  108. System.out.println(jc.getName()+"---"+jc.getAge());
  109. jc.eat();
  110. jc.sleep();
  111. jc.jump();
  112. System.out.println("-----------------");
  113. JumpCat jc2 = new JumpCat("加菲猫",2);
  114. System.out.println(jc2.getName()+"---"+jc2.getAge());
  115. jc2.eat();
  116. jc2.sleep();
  117. jc2.jump();
  118. //定义跳高狗并进行测试的事情自己完成。
  119. }
  120. }
  • 运行结果




转载于:https://www.cnblogs.com/lutianfei/p/5233377.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值