`
holdbelief
  • 浏览: 707504 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

第三课时:面向对象(2)

阅读更多

    一、成员变量与局部变量

    图片

 

二、类的继承

语法:

修饰符 class SubClass extends SuperClass

{

    // 类的定义部分

}

Java类具有单继承的特点,每个子类只有一个直接父类,但注意“直接”两字,Java类可以有许多间接父类,但直接父类只能有一个。

例如:

java.lang.Object
  java.util.AbstractCollection<E>
      java.util.AbstractList<E>
          java.util.ArrayList<E>
而:class SubClass extends Base1, Base2, Base3{} 这样写法报编译错误。

继承示例:

1、继承父类的属性和方法

Fruit.java

package extendsdemo;

public class Fruit {
 public double weight;
 public void info(){
  System.out.println("父类输出:我是一个水果!重量" + this.weight + "g!");
 }
}
Apple .java

package extendsdemo;

public class Apple extends Fruit {
 // do nothing
}

MainClass.java

package mainclasspackage;

import extendsdemo.Apple;

public class MainClass {
 public static void main(String[] args) {
  Apple apple = new Apple(); // Apple 类本身是一个空类,但它继承了父类的weight属性和info方法。
  apple.weight = 56D;
  apple.info();
 }
}
2、重写父类的属性和方法(重写也称为覆盖Override)
父类:Bird

package extendsdemo;

public class Bird {
 public void fly(){
  System.out.println("我在填空自由自在的飞翔!");
 }
}
子类:Ostrich

package extendsdemo;

public class Ostrich extends Bird {
 public void fly(){
  System.out.println("我只能在地上奔跑!");
 }
}

3、方法的重载遵循“两同、两小、一大”规则

“两同”:方法名相同,形参列表相同;

“两小”:指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常应比父类方法声明抛出的异常类更小或相等;

“一大”:子类的方法的访问权限应比父类方法更大或相等;

尤其需要指出的,覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法。

下面示例都不是重写,子类的方式是不同于父类的另一个方法:

父类:BaseClass.java

package extendsdemo;

public class BaseClass {
 public Ostrich findBird(String str1, int i1){
  Ostrich ostrich = new Ostrich();
  return ostrich;
 }
}

子类:SubClass.java

package extendsdemo;

public class SubClass extends BaseClass {
 /**
  * 1、形参列表不同
  * 2、子类findBird方法的返回值 > 父类findBird方法的返回值
  * 3、子类findBird方法的访问修饰符 < 父类findBird方法的访问修饰符
  * @param str1
  * @return
  */
 protected Bird findBird(String str1){
  Bird bird = new Bird();
  return bird;
 }
}
4、子类中如何调用父类的成员属性、成员方法、构造函数——super关键字

package extendsdemo;

public class Ostrich extends Bird {
 /**
  * this 指的是当前对象
  * super 指的是当前对象的父类对象
  * 在构造函数中 this、super必须卸载构造函数的第一行
  * 在普通方法中,可以使用super.方法名 调用父类的方法
  * super与this相同,不能与static关键字同时使用
  */
 public Ostrich(){
//  super();
  this("");
  System.out.println("我是子类的构造函数");
 }
 
 public Ostrich(String str){
//  super();
  System.out.println("我是子类被重载的构造函数,我有一个形参");
 }
 
 public void fly(){
  System.out.println("我只能在地上奔跑!");
  
  super.fly();
 }
 
 public static void test(){
  this.fly(); // 这里会报编译错误
  super.fly(); // 这里会报编译错误
 }
}
子类构造函数调用父类构造函数的顺序:

图片

 

5、使用继承的注意点 

    为了保证父类良好的封装性,不会被子类随意改变,设计父类通常应该遵循如下规则:

  • 尽量隐藏父类的内部数据。尽量把父类的所有属性都设置成 private 访问类型,不能让子类直接访问父类的属性。
  • 不要让子类可以随意访问、修改父类的方法。父类中那些仅为辅助其他的工具方法,应该使用 private 访问控制符修饰,让子类无法访问该方法;如果父类中的方法需要被外部类调用,必须以 public 修饰,但又不希望子类重写该方法,可以使用 final 修饰符;如果希望父类的某个方法被子类重写,但不希望被其它类自由访问,可以使用 protected 来修饰该方法。
  • 尽量不要再父类构造器中调用将要被子类重写的方法。例如:

class Base{

    public Base(){

        test();

    }

    public void test(){                                                                    // ① 号 test 方法

        System.out.println("将被子类重写的方法");

    }

}

 

class Sub extends Base{

    private String name;

    public void test(){                                                                    // ② 号 test 方法

        System.out.println("子类重写父类的方法,其 name 字符串的长度" + name.length());

    } 

    public static void main(String[] args){

        // 下面代码会引发空指针异常

        Sub s = new Sub();

    }

}

    当系统试图创建 Sub 对象时,同样会先执行其父类的构造器,如果父类的构造器调用了被其子类重写的方法,则变成了调用被子类重写后的方法。当创建 Sub 对象时,会先执行 Base 类中的 Base 构造器。而 Base 构造器中调用了 test 方法——并不是① 号 test 方法,而是调用了② 号 test 方法,此时 Sub 对象的 name 属性是 null,因此将引发空指针异常。

  • 如果想把某些类设置为最终类,即不能被当成父类,则可以使用 final 修饰这个类,例如 JDK 提供的 java.lang.String 和 java.lang.System 类。除此之外,或者使用 private 修饰这个类中的所有构造器,从而保证子类无法调用该类的构造器,也就无法继承该类。对于把所有构造器都是用 private 修饰的父类而言,可以另外提供一个静态的方法,用于创建该类的实例。

例如:

BaseClass1:

package baseclasspackage;

public class BaseClass1{
 
 /**
  * 只提供一个构造子,并且该构造子属私有 private 类型,该类无法被继承,
  * 且其他类也无法在调用该构造子,所以需要通过提供一个静态工厂方法提供
  * 该类的实例
  */
 private BaseClass1(){}
 
 /**
  * 静态工厂方法获得类的实例
  * @return
  */
 public static BaseClass1 getInstance(){
  return new BaseClass1();
 }
}

SubClass1:

package subclasspackage;

import baseclasspackage.BaseClass1;

public class SubClass1 extends BaseClass1 { // 发生编译错误,无法继承 BaseClass1

}

BaseClass2 :

package baseclasspackage;
/**
 * 使用 final 关键字修饰的类,无法被继承
 * @author Administrator
 */
public final class BaseClass2 {

}

BaseClass2 :
package subclasspackage;

import baseclasspackage.BaseClass2;

public class SubClass2 extends BaseClass2 { // 发生编译错误

}

如何实例化BaseClass1和BaseClass2:

MainClass:

package mainclasspackage;

import baseclasspackage.BaseClass1;
import baseclasspackage.BaseClass2;

public class MainClass {
 public static void main(String[] args) {
  BaseClass1 b1 = new BaseClass1(); // 发生编译错误,无法调用私有的构造函数
  BaseClass1 b1_ = BaseClass1.getInstance(); // 通过调用静态工厂方法,获得BaseClass1的实例
  
  BaseClass2 b2 = new BaseClass2(); // 使用 final 关键字修饰的 BaseClass2 在实例化上与普通类相同
 }
}

6、利用组合实现复用

 示例:

Animal:

package compositedemo;

public class Animal {
 private void beat(){
  System.out.println("心脏跳动……");
 }
 public void breath(){
  beat();
  System.out.println("吸一口气、呼一口气、呼吸中……");
 }
}
Bird :

package compositedemo;

public class Bird {
 //将原来的父类嵌入原来的子类,作为子类的一个组合成分
 private Animal a;
 public Bird(Animal a)
 {
  this.a = a;
 }
 //重新定义一个自己的breath方法
 public void breath()
 {
  //直接复用Animal提供的breath方法来实现Bird的breath方法。
  a.breath();
 }

 public void fly()
 {
  System.out.println("我在天空自在的飞翔...");
 }
}

Wolf :
package compositedemo;

public class Wolf {
 //将原来的父类嵌入原来的子类,作为子类的一个组合成分
 private Animal a;
 public Wolf(Animal a)
 {
  this.a = a;
 }
 //重新定义一个自己的breath方法
 public void breath()
 {
  //直接复用Animal提供的breath方法来实现Bird的breath方法。
  a.breath();
 }
 public void run()
 {
  System.out.println("我在陆地上的快速奔跑...");
 }
}

MainClass:
package compositedemo;

public class MainClass {
 public static void main(String[] args)
 {
  //此时需要显式创建被嵌入的对象
  Animal a1 = new Animal();
  Bird b = new Bird(a1);
  b.breath();
  b.fly();
  //此时需要显式创建被嵌入的对象
  Animal a2 = new Animal();
  Wolf w = new Wolf(a2);
  w.breath();
  w.run();  
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

作业部分:

新建一个类Bird
public class Bird{
 // 属性1,实例属性,鸟的颜色 String
 // 属性2,实例属性,鸟的种类 String
 // 属性3,类属性(静态属性),鸟的眼睛的数量 int
 // 属性4,类属性(静态属性),鸟的翅膀的数量 int
 // 属性5,实例属性,是否会飞 boolean

 /*
         * 为所有的实例属性编写getter、setter
  */

 // 第一个构造函数:空的构造函数
 // 第二个构造函数:为所有实例属性初始化
 public Bird(String color, String sort, boolean flag){
  // ...
 {
 
 // 使用静态块初始化所有类属性
 static{
  Bird.鸟眼睛的数量 = 2;
  Bird.鸟翅膀的数量 = 2;
 }

 // 添加一个方法,作用是:输出Bird中的各个属性
 public void showBird(){
  // ...
 } 
}

新建一个Bird类的子类,名字叫Ostrich
public class Ostrich extends Bird{
 // 覆盖直接父类(Bird)的showBird()方法
 // 覆盖顶级父类(java.lang.Object)的toString()方法,方法返回值是String,字符串包含的信息:颜色、种类、是否会飞
}


MainClass{
 Ostrich ostrich = new Ostrich();
 ostrich.set颜色();
 ostrich.set种类();
 ostrich.set是否会飞();

 // 修改两个静态属性,

 调用Ostrich类重载之后的showBird()方法和toString()方法。
}

分享到:
评论

相关推荐

    Python基础编程与实践教案第二十六课时Python面向对象编程(下).doc

    在本课时中,学生将深入学习面向对象编程的几个关键概念,包括继承、抽象基类、多态、多重继承、混合继承以及运算符重载。 1. **继承**:继承是面向对象编程中的一种机制,允许一个类(子类)从另一个类(父类)...

    视频2018 07第3章 面向对象方法、软件架构、应用集成技术

    通过观看"07第3章 面向对象方法、软件架构、应用集成技术.mp4"的视频,并结合"课时07:第3章:面向对象方法、软件架构、应用集成技术(彩色共享版).pdf"的课件,学员可以更深入地学习这些关键概念,提高自己的专业...

    C++面向对象上机练习(三)

    根据提供的文件内容,本篇面向对象上机练习主要涉及C++中的类设计、对象创建、成员函数的使用、构造函数、以及具体的工资计算业务逻辑。以下知识点将详细阐述这些方面的内容。 ### 类与对象设计 - **类的定义**:...

    C++课程-高质量C++编程_课时_大纲

    ### 第三章:函数 - **3.1 函数定义与调用**:理解函数的作用,学习函数参数、返回值以及函数重载。 - **3.2 变量作用域与存储类别**:解释局部变量、全局变量、静态变量和extern关键字。 - **3.3 函数指针**:理解...

    课时60第三十五回 面向对象.mp4

    Python原来这么简单(win系统 提高篇)

    5-3面向对象的功能实现.docx

    - 使用广东教育出版社的信息技术(选修一)《算法与程序设计》第五章第三节内容作为核心框架。 - 结合上海科教版普通高中信息技术课程实验教材《算法与程序设计》的相关章节,以补充和完善教学内容。 - 采取讲解...

    Windows编程和面向对象技术

    2. C++与面向对象:讲解C++的基础语法,类和对象,以及面向对象四大特性。 3. 创建Windows应用程序:实践如何使用C++和Windows API编写简单的桌面程序。 4. 高级Windows编程:涉及线程、内存管理、文件I/O等复杂主题...

    Python基础教程-第7章-Python面向对象.ppt

    在本章"Python基础教程-第7章-Python面向对象"中,我们将深入探讨这一主题。 首先,面向对象编程(OOP)是一种编程范式,它基于"对象"的概念,这些对象包含数据(属性)和操作这些数据的方法(函数)。与面向过程...

    魔方1.0版课时3 源码

    在本课程中,我们主要探讨的是“魔方1.0版”的第三个课时,这个课时专注于源码的实现和理解。在这个阶段,学生将学习如何编写和理解用于魔方旋转和放大缩小功能的程序代码。为了更好地理解这些概念,我们将深入到...

    c++的课件(c++面向对象编程语言)

    接着是"第三章 类和对象(一)(3 学时).ppt",这章重点讲述C++的核心概念——类和对象。类是面向对象编程的基础,它定义了数据和操作这些数据的方法。对象则是类的实例,通过创建对象来使用类中的属性和方法。这...

    python课时安排-《Python基础》课程标准-64课时.pdf

    - **面向对象编程**:讲解类、对象和继承的概念,以及如何设计和实现简单的面向对象程序。 - **文件操作和异常处理**:教授读写文件、错误处理和异常捕获。 - **数据结构**:介绍列表、元组、字典和集合,以及如何...

    《python》课程教学大纲.doc.doc

    * 第三章:Python 的流程控制 * 第四章:列表、元组、字典和集合 * 第五章:函数与模块 * 第六章:文件 I/O * 第七章:面向对象编程 * 第八章:错误和异常 * 第九章:os、sys 模块及应用 * 第十章:正则表达式 * 第...

    部编版第二课时作业.doc

    驼峰命名法是编程中常用的变量命名规范,特别是在面向对象编程中。这种命名方式要求每个单词的首字母大写,如“myVariableName”。在创建一个由三个单词组成的变量时,例如“studentFirstName”,可以先定义这个变量...

    java学习 1第一章 概论.ppt

    教材推荐的是由印旻主编的《JAVA语言与面向对象程序设计(第2版)》,同时提供了SUN的J2SE1.5 API文档作为主要参考,还有其他几本专业书籍,如Bruce Eckel的《JAVA编程思想》、孙卫琴的《Java面向对象编程》以及...

    基于VB.NET的Windows应用程序设计

    掌握面向对象的编程思想 能够使用Visual Studio.NET图形化界面开发环境 课时:108 课时 分为两部分 讲课部分:36 课时,课堂教学 实践部分:72 课时,课程实验 培养目标  通过本课程的学习,学生可以具备掌握使用...

    文字稿(更新到第三十课时)1

    课程通过实例教学,逐步揭示游戏架构从简单到复杂、从无到有的构建过程,使学习者能够理解并运用相关C#核心基础、数据结构、面向对象设计原则和架构理论。通过这个课程,开发者不仅能学会如何构建一个稳定的、扩展性...

    48课时 java考试题

    11. **面向对象的三大特征** - 继承:允许创建具有相似特性的类的层次结构。 - 封装:隐藏对象的具体实现细节。 - 多态:一个接口可以有不同的实现。 12. **类成员的限定词补充** - `private`:私有成员,只能...

    第1章立体几何初步第6课时平面的基本性质同步练习(必修2).doc

    本章的第六课时聚焦于平面的基本性质,这些性质是理解更复杂几何问题的基础。 1. 命题分析: - ① 梯形的四个顶点在同一平面内:这是正确的,因为梯形的对角线互相平分,意味着它们的交点以及四个顶点都在同一平面...

    C++课件人名邮电大学版

    ### C++基础知识与面向对象程序设计 #### 一、课程介绍 - **课程性质与目的**:本课程作为计算机及相关专业本科生的通识基础课,旨在让学生了解面向对象的程序设计思想,掌握C++语言的基本知识。课程内容覆盖了封装...

    邓俊辉数据结构C++语言版第3版 + 习题解析第3版 + 随书代码 高清完整文字版

    《数据结构(C++语言版 第3版)/清华大学计算机系列教材》,主教材按照面向对象程序设计的思想,根据作者多年的教学积累,系统地介绍各类数据结构的功能、表示和实现,对比各类数据结构适用的应用环境;结合实际问题...

Global site tag (gtag.js) - Google Analytics