Com.Java.Basis 第十课 《封装+继承》(一)

简介: Com.Java.Basis 第十课 《封装+继承》(一)

第一模块:了解面向对象的三大特征的定义

封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在java中通过关键字private,protected和public实现封装。什么是封装?封装把对象的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。


封装的作用:

① 对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。


②对象的数据封装特性还可以把对象的私有数据和公共数据分离开,保护了私有数据,减少了可能的模块间干扰,达到降低程序复杂性、提高可控性的目的。

package car;
public class Car {
  private String name;//车名
  private String color;//颜色
  private String engine;//引擎
  public Car() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Car(String name, String color, String engine) {
    super();
    this.name = name;
    this.color = color;
    this.engine = engine;
  }
  /**
   * @return the name
   */
  public String getName() {
    return name;
  }
  /**
   * @param name the name to set
   */
  public void setName(String name) {
    this.name = name;
  }
  /**
   * @return the color
   */
  public String getColor() {
    return color;
  }
  /**
   * @param color the color to set
   */
  public void setColor(String color) {
    this.color = color;
  }
  /**
   * @return the engine
   */
  public String getEngine() {
    return engine;
  }
  /**
   * @param engine the engine to set
   */
  public void setEngine(String engine) {
    this.engine = engine;
  }
  @Override
  public String toString() {
    return "Car [name=" + name + ", color=" + color + ", engine=" + engine + "]";
  }
}

package com.animal;
public class Dog extends Animal{
  int age;
    String name;
    char cry;
   public Dog() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Dog(int age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  // 覆盖(重写)方法
   public void cry() {
          System.out.println("旺旺");
      }
      public void eat() {
          System.out.println("我是狗,我爱吃骨头");
      }
      public void sleep() {
          System.out.println("我是狗,7:00睡觉");
      }
}

package com.animal;
/**
 * 一个主人养了猫和狗,猫和狗都有自己爱吃的东西,主人在喂它们
 * 的时候,如果既要判断是猫还是狗,再判断他们分别爱吃什么,就显得很麻烦。
 * 如果主人养了很多种动物,这样的重复判断,就会浪费很多时间。有什么办法,
 * 能让主人拿到一种食物就知道这是哪种动物的,就好了。
 * @author MZFAITHDREAM
 *
 */
public class Animal {
  public String age;
    public String name;
    public char cry;
    public Animal() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Animal(String age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    // 动物类里面有叫和吃两个方法
    public void cry() {
        System.out.println("我不知道叫什么");
    }
    public void eat() {
        System.out.println("我不知道吃什么");
    }
    public void sleep() {
      System.out.println("我不知道几点睡觉");
    }
  @Override
  public String toString() {
    return "Animal [age=" + age + ", name=" + name + ", cry=" + cry + "]";
  }
}

继承:

继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。 [1]


Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。


这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。比如可以先定义一个类叫车,车有以下属性:车体大小,颜色,方向盘,轮胎,而又由车这个类派生出轿车和卡车两个类,为轿车添加一个小后备箱,而为卡车添加一个大货箱。


(1)继承关系是传递的。若类C继承类B,类B继承类A(多层继承),则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。继承来的属性和方法尽管是隐式的,但仍是类C的属性和方法。继承是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段。


(2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。


(3)继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。


(4)继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。


(5)提供多重继承机制。从理论上说,一个类可以是多个一般类的特殊类,它可以从多个一般类中继承属性与方法,这便是多重继承。Java出于安全性和可靠性的考虑,仅支持单重继承,而通过使用接口机制来实现多重继承。


多态:多态性是面向对象编程的又一个重要特征,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。


对面向对象来说,多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是大家通常所说的多态性。


Java 实现多态有 3 个必要条件:继承、重写和向上转型。只有满足这 3 个条件,开发人员才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而执行不同的行为。

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。

这一篇文章介绍的是Java面向对象的继承:

 

案例一:了解继承的结构.这里没有测试类具体内容看下面的案例。

package extends1;
public class Person {
  private String name;
  private int age;
  public Person() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Person(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  }
  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;
  }
}
package extends1;
/**
 * 定义老师类(姓名,年龄,教书())
 * @author Administrator
 *
 */
public class Student extends Person{
  public Student() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Student(String name, int age) {
    super(name, age);
  }
  public void study(){
    System.out.println("学生学习");
  }
}

package extends1;
public class Teacher extends Person{
  public Teacher() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Teacher(String name, int age) {
    super(name,age);
  }
  public void teach() {
    System.out.println("用爱给每一个学生");
  }
}

案例二:final.

package final1;
public  class Person {
  private String name;
  private int age;
  public Person() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Person(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  }
  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  void speaking(){
    System.out.println("大声说话");
  }
}
package final1;
/**
 * 定义老师类(姓名,年龄,教书())
 * @author Administrator
 *
 */
public class Student extends Person{
  static int num = 10;
  public Student() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Student(String name, int age) {
    super(name, age);
  }
  public void study(){
    System.out.println("学生学习");
  }
}

package final1;
public class Test {
  /**
   * @param args
   */
  public static void main(String[] args) {
//    Student stu = new Student();
    System.out.println(Student.num);
  }
}

案例三:super:

package super1;
public class Person {
  private String name;
  private int age;
  public Person(String name, int age) {
    System.out.println("这是Person中的有参数构造方法");
    this.name = name;
    this.age = age;
  }
  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 void eat(){
    System.out.println("需要每餐都吃饭");
  }
}
package super1;
public class Student extends Person{
  private String stuId;//学号
  public Student() {
    //调用的是父类中的无参数构造方法
    super("王刚",50);
    // TODO Auto-generated constructor stub
    System.out.println("这是Student中的有参数构造方法");
  }
  public Student(String name, int age, String stuId) {
    super(name, age);
    this.stuId = stuId;
  }
  public String getStuId() {
    return stuId;
  }
  public void setStuId(String stuId) {
    this.stuId = stuId;
  }
  public void study(){
    System.out.println("每天都要学习");
  }
  @Override
  public void eat(){
    //子类要对父类的某个方法进行补充
    super.eat();
    System.out.println("除了星期六和星期天");
  }
}

package super1;
public class StudentTest01 {
  /**
   * @param args
   */
  public static void main(String[] args) {
    // 创建一个学生对象
    Student stu = new Student();
    stu.eat();
  }
}

案例四:修饰符:

 

package xiushifu;
public class Son extends Student{
  public void speaking(){
    sleep();
  }
}

package xiushifu;
public class Student {
  //学习
  private void study(){
    System.out.println("学习");
  }
  void eat(){
    System.out.println("干饭");
  }
  protected void sleep(){
    System.out.println("睡觉");
  }
  public void play(){
    System.out.println("打游戏");
  }
}
package xiushifu;
public class Test {
  /**
   * @param args
   */
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Student stu = new Student();
    stu.sleep();
    stu.eat();
    stu.play();
  }
}

案例五代码实战:真正的了解继承的原理:

package com.animal;
/**
 * 一个主人养了猫和狗,猫和狗都有自己爱吃的东西,主人在喂它们
 * 的时候,如果既要判断是猫还是狗,再判断他们分别爱吃什么,就显得很麻烦。
 * 如果主人养了很多种动物,这样的重复判断,就会浪费很多时间。有什么办法,
 * 能让主人拿到一种食物就知道这是哪种动物的,就好了。
 * @author MZFAITHDREAM
 *
 */
public class Animal {
  public String age;
    public String name;
    public char cry;
    public Animal() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Animal(String age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    // 动物类里面有叫和吃两个方法
    public void cry() {
        System.out.println("我不知道叫什么");
    }
    public void eat() {
        System.out.println("我不知道吃什么");
    }
    public void sleep() {
      System.out.println("我不知道几点睡觉");
    }
  @Override
  public String toString() {
    return "Animal [age=" + age + ", name=" + name + ", cry=" + cry + "]";
  }
}

package com.animal;
public class Cat extends Animal{
  int age;
    String name;
    char cry;
   public Cat() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Cat(int age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  public void cry() {
          System.out.println("喵喵");
      }
      public void eat() {
          System.out.println("我是猫,我爱吃鱼");
      }
      public void sleep() {
          System.out.println("我是猫,5:00睡觉");
      } 
}

package com.animal;
public class Dog extends Animal{
  int age;
    String name;
    char cry;
   public Dog() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Dog(int age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  // 覆盖(重写)方法
   public void cry() {
          System.out.println("旺旺");
      }
      public void eat() {
          System.out.println("我是狗,我爱吃骨头");
      }
      public void sleep() {
          System.out.println("我是狗,7:00睡觉");
      }
}

package com.animal;
public class Duck  extends Animal{
  int age;
    String name;
    char cry;
  public Duck() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Duck(int age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  @Override
  public void cry() {
    System.out.println("duck duck");
  }
  @Override
  public void eat() {
    System.out.println("我是鸭子 :爱吃vegetanles");
  }
}

package com.animal;
public class Rabbit  extends Animal{
  int age;
    String name;
    char cry;
  public Rabbit() {
    super();
    // TODO Auto-generated constructor stub
  }
  public Rabbit(int age, String name, char cry) {
    super();
    this.age = age;
    this.name = name;
    this.cry = cry;
  }
  public void cry() {
    System.out.println("兔子十点睡");
  }
  @Override
  public void eat() {
    System.out.println("我是一个rabbit:吃carrot");
  }
}

                   

相关文章
|
Java
Com.Java.Basis 第十课 《封装+继承》(二)
Com.Java.Basis 第十课 《封装+继承》(二)
46 0
Com.Java.Basis 第十课 《封装+继承》(二)
|
27天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
3天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
28 6
|
18天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
16天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
18天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
12天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
12天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
34 3
|
13天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
18天前
|
缓存 Java 开发者
Java多线程并发编程:同步机制与实践应用
本文深入探讨Java多线程中的同步机制,分析了多线程并发带来的数据不一致等问题,详细介绍了`synchronized`关键字、`ReentrantLock`显式锁及`ReentrantReadWriteLock`读写锁的应用,结合代码示例展示了如何有效解决竞态条件,提升程序性能与稳定性。
60 6