Java——类的封装、继承与多态

一.类和对象

1.类

类是数据以及对数据的一组操作的封装体。

类声明的格式:

类声明

{

  成员变量的声明;

  成员方法的声明及实现;

}

1.1 声明类

[修饰符] class 类<泛型> [extends 父类] [implements 接口列表]

<泛型>——类的参数,带有参数的类成为泛型类。

1.2 声明成员变量和成员方法

成员变量声明格式:[修饰符] 数据类型 变量[=表达式]{,变量[=表达式]};

成员方法——用来描述对成员变量进行的操作,格式:[修饰符] 返回值类型 方法([参数列表])[throws 异常类]
{
   语句序列;
   [return [返回值]];
}

例如:

public class MyDate   //类声明

{

  int year,month,day;  //声明成员变量

  void set(int y,int m,int d)   //成员方法,设置日期值

  {                                    //无返回值,有三个参数

      year=y;

      month=m;

      day=d;

  }

}

2.对象

类本身不参与程序运行,实际参与运行的是类的对象。

对象是类的实例(instance),即类的取值。类的一个对象能够获得并保存类的一个实例。

类比:类——对象——类的实例

    数据类型———变量——取值

    例如:int类型——变量i——取值10

2.1 MyDate d=new MyDate();//声明对象,创建实例并赋值

2.2 引用对象的成员变量和调用成员方法

    对象.成员变量

    对象.成员方法([参数列表])

注:Java的内存自动管理机制,能够跟踪存储单元的使用情况,自动回收不再被使用的资源,所以,程序中不需要释放对象占用的空间资源。

Java的类是引用数据类型,两个对象之间的赋值是引用赋值,对象赋值过程中没有创建新的实例。

(注:1、“==”作用在引用数据类型间,判断内存地址是否相等,想判断内容实体用equals;
    2、基本传值传参传的是副本,修改后原值不变;引用传值传参穿的是地址,修改后原值改变。

  引用类型 就是只变量中存储的不是值而是一个内存中的地址的数据类型
  也就是说 变量中存储了这个变量的值所在内存中的地址 每次调用这个变量都是引用这个地址而得到真正的值 所以叫引用类型 。

  通俗说,将变量名与变量值分开,比如Student s=new Student(),s就是个引用类型的变量,s这个名分配在栈空间里,但是s它指向的值在堆空间里)

二、类的封装性

1.构造方法

用于创建类的一个实例并对实例的成员变量进行初始化。构造方法与类同名;构造方法通过new运算符调用。

构造方法和成员方法的不同之处:

A.作用不同:成员方法实现对类中成员变量的操作;构造方法用于创建类的实例并对实例的成员变量进行初始化。

B.调用方式不同:成员方法通过对象调用;构造方法通过new运算符调用。

例如:

public class MyDate

{

  public MyDate (int y,int m,int d)

  {

    year=y;month=m;day=d;

  }

}

使用new运算符调用自定义的构造方法,参数必须符合构造方法的声明。

MyDate d=new MyDate(2009,7,18);//创建实例并初始化成员变量

拷贝构造方法

一个类的构造方法,如果其参数是该类对象,称为拷贝构造方法,它将创建的新对象初始化为形式参数的实例值,实现对象复制功能。

Java不提供默认拷贝构造方法。

public class MyJava {

public static void main(String[] args) {
  // TODO 自动生成的方法存根
  MyJava d1=new MyJava(2016,4,27);
  MyJava d2=new MyJava(d1);
  System.out.print(d2.year);
 }

private int year;
 private int month;
 private int day;
 
public MyJava(int y,int m,int d){
 year = y;
    month=m;
 day=d;
}
public MyJava(MyJava d){
 year = d.year;
    month=d.month;
 day=d.day;
}

输出:2016

2.this引用和instanceof 对象运算符

2.1 this引用

(1)指代对象本身 this

this用于指代调用成员方法的当前对象自身。

(2)访问本类的成员变量和成员方法

this.成员变量

this.成员方法([参数列表])

public MyDate(int year,int month,int day)

{  //指定参数的构造方法,参数与成员变量同名

  this.year=year;//this.year指定当前对象的成员变量,year指参数

  this.month=month;//this引用不能省略

  this.day=day;  

}

public MyDate()   //默认构造方法,重载

{

  this(1970,1,1);//调用本类已定义好的构造方法

}

public MyDate(MyDate d)

{

  this(d.year,d.month,d.day);  

}

2.2 instanceof 对象运算符

判断一个对象是否属于指定类及其子类,返回boolean类型。

例:MyDate d=new MyDate();

d instanceof MyDate

//返回true,d是MyDate类的实例

3 访问控制

3.1 类的访问控制权限

声明一个类可使用的权限修饰符只有两种: public 和 缺省

  共有权限public,可被所有类访问

  缺省权限无修饰符,可被当前包(当前文件夹)中的类访问。

一个源程序文件中可声明多个类,但用public修饰的类只能有一个,且该雷鸣必须与文件名相同。

  源程序文件MyDate.java中可声明多个类如下:

    public class MyDate  //公有权限的类

    class MyDate_ex //缺省权限的类

类的成员有4种访问控制权限

private—声明私有成员,该成员仅能被当前类的成员访问。(当前类)

缺省—没有修饰符表示缺省权限,说明该成员能被当前类以及当前包中的其他类访问,也称在当前包中可见。(当前包)

protected—声明保护成员,该成员能被当前类及其子类、或当前包中的其他类访问,也称在子类中可见。(子类)

public——声明公有成员,该成员可被所有类访问。(所有)

声明set()和get()方法存取对象的属性 —值对象的某个特性或特征

  Java约定,存取对象属性的方法分别是set()和get()。

    public void set(int y,int m,int day)//设日期

    public void set(MyDate d)//设置日期,重载

    public int getYear()//获取年份

4 静态成员

实例成员—属于对象,包括实例成员变量和成员方法。只有创建了实例,才能通过对象访问实例成员变量和实例成员方法。

静态成员—属于类,需要用关键字static标识。包括类成员变量和类成员方法。即使没有创建实例,也可以通过类名直接访问类静态成员变量和调用静态成员方法。

5 析构方法

——用于释放实例并执行特定操作。

public void finalize() //约定析构方法名为finalize

{                           //finalize()没有参数,也没有返回值

  语句序列;

}                          //一个类只能有一个finalize()方法,qiefinalize()不允重载

  Java的内存自动管理机制能够释放不再将被使用的对象,所以,通常类不需要设计析构方法。

如果需要在释放对象时执行特定操作,则类可以声明析构方法。

注:A.当对象超出它的作用域时,Java将执行对象的析构方法。

  B.一个对象也可以调用析构方法来释放对象自己。

  C.不能使用已被析构方法释放的对象,否则将产生运行错误。

例如:d.finalize(); //调用对象的析构方法

6 浅拷贝与深拷贝

浅拷贝—一个类的拷贝构造方法,使用一个已知实例对新创建实例的成员变量逐个赋值,这种方法称为浅拷贝。

  当对象的成员变量是基本数据类型时,两个对象的成员变量已有存储空间,赋值运算传递值,所以浅拷贝能够赋值实例。

  当对象的成员变量是引用数据类型时,浅拷贝不能实现对象复制功能,需要深拷贝。

  public class Person

{

  String name;                     //姓名

MyDate birthday;                //生日

public Person(String name,MyDate birthday)   //构造方法

  {

    this.name=name;

    this.birthday=birthday;    //引用赋值

  }

public Person(Person p)          //拷贝构造方法,复制对象

  {

    this(p.name,p.birthday);

  }  

 }

深拷贝—当一个类包含引用类型的成员变量时,该类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并初始化为形式参数实例值,这种复制方法称为深拷贝。

三 类的继承

1 由继承派生类

继承:根据一个已知的类由继承方式创建一个类,使新创建的类自动拥有被继承类的全部成员。

父类/超类——被继承类;子类/派生类——通过继承产生的新类

父类和子类的关系:

A.子类自动拥有父类的全部成员,包括成员变量和方法等,使父类成员得以传承和延续;

B.子类可以更改从父类继承来的成员,使父类成员适应新的需求;

C.子类也可以增加自己的成员,使类的功能得以扩充。

D.子类不能删除父类的成员。

声明继承类:[修饰符] class <泛型>[extends 父类] [implements 接口列表]

注:Java的类是单继承的,一个类只能有一个父类,不能有多个父类。

1.1 继承原则

(1)子类继承父类的成员变量

(2)子类继承父类除构造方法以外的成员方法

(3)子类不能继承父类的构造方法

子类没有继承父类的构造方法,因为父类的构造方法只能创建父类实例并初始化,无法创建实例。

例如:父类声明构造方法Person(String,MyDate),当子类没有生命Student(String,MyDate)构造方法时,下列语句是错误的:

      Student s1=new Student("李小明",new MyDate(1979,3,15));//语法错,构造方法参数不匹配

(4)子类可以增加成员,可以重定义从父类继承来的成员,但不能删除。

1.2 子类的构造方法

子类对象包含从其父类继承来的成员变量,以及子类声明的成员变量,子类构造方法必须对这些成员变量进行初始化。而父类构造方法已对父类声明的成员变量进行了初始化,因此,子类构造方法必须调用父类的某一个构造方法。

1.2.1 使用super()调用父类构造方法

     在子类的构造方法体中,可以使用"super引用"调用父类的构造方法。其语法如下:

              super([参数列表])

     public Student(String name,MyDate birthday,String spec)

     {

       super(name,birthday);   //super()调用必须是第一条语句  调用父类同参数的构造方法

       this.speciality=spec;

     }

1.2.2 默认执行super()

以下两种情况,Java默认值型super(),调用父类的构造方法。

(1)当一个类没有声明构造方法时,Java为该类提供默认构造方法,调用super()执行父类无参数的构造方法。

  public Student()    //Java提供的默认构造方法

  {

      super();     //调用父类构造方法Person()

  }

如果父类Person没有声明构造方法Person(),则上述语句产生编译错误。因此,每个类都要声明无参数的构造方法,即使自己不用,也要为子类准备着。

      public Person()   //Java提供的默认构造方法

      {

        super();        //调用父类构造方法Object()

      }

(2) 如果子类的构造方法没有调用super()或this(),Java将默认执行super()。

      public Student()

      {

        super();

        speciality="";

      }

1.3 类的多态性

类的多态性表现为方法的多态和类型的多态。

方法的多态:包括方法的覆盖和重载,为一种功能提供多种实现。

类型的多态:子类是一种父类类型。

子类重定义父类成员包括:

(1)重定义父类的成员变量,则隐藏父类的成员变量;

(2)重定义父类的成员方法,如果参数列表相同,则覆盖父类的成员方法,否则重载。

子类重定义父类成员表现出多态,父类对象引用父类成员,子类对象引用子类成员。

在子类的成员方法中,如果需要引用被子类隐藏或覆盖的父类同名成员,可以用super引用。格式如下:

super.成员变量

super.成员方法([参数列表])

子类对象即是父类对象——子类对象包含父类的所有成员变量,isA关系表现为继承具有“即是”性质。 new Person()/Student() instanceof Person

父类对象引用子类实例——父类对象能够引用子类实例

Person p=new Student();

1.3.1 编译时多态和运行时多态

 (1)编译时多态

    对于多个同名方法,如果在编译时能够确定执行同名方法中的哪一个,则称编译时多态。

方法的重载—都是编译时多态性

    方法的覆盖—当对象引用本类实例时,为编译时多态;

                    否则,运行时多态。

   Person p1=new Person("李小明",new MyDate(1979,3,15));

   System.out.println("p1:"+p1.toString()); //编译时多态性,执行Person类的toString()

  (2)运行时多态

    父类对象只能执行哪些在父类中声明、被子类覆盖了的子类方法,如toString(),不能执行子类中新增加的成员方法。

程序运行时,Java从实例所属的类开始寻找匹配的方法执行,如果当前类中没有匹配方法,则沿着继承关系逐层向上,依次在父类和各祖先类中寻找匹配方法,直到Object类。

四 类的抽象性

抽象类特点:1)抽象类中可以不包含抽象方法,但是包含抽象方法的类必须被声明为抽象类;

2)构造方法、静态成员方法不能被声明为抽象方法;

        3)一个非抽象类必须实现从父类继承来的所有抽象方法,如果不能实现父类的所有抽象方法,则该类必须声明为抽象类;

        4)抽象类不能被实例化,不能创建抽象类实例。

时间: 2024-10-03 15:01:31

Java——类的封装、继承与多态的相关文章

java类的封装 继承 多态

1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ public class GuessNumberDemo { public static void main(String[] args) { int number = (int) (Math.random() * 100) + 1; while (true) { System.out.println("

黑马程序员--oc 类的封装 继承 和多态

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 成员变量的命名规范: 成员变量名要以 _开头 作用: 1.可以让成员变量和get方法的名称区分开 2.可以和局部变量区分开,一看到以_开头的变量一般都是成员变量 封装: 在定义成员变量时,尽量不要用@public 这种写法 ,而是使用set方法和get方法 @interface Student : NSObject { int _age; } /* set方法: 作用:提供一个方法给外界设置成

类的封装 继承和多态

package 银行账户管理;import java.text.SimpleDateFormat;   //常用日期操作工具类import java.util.Calendar;     //使用默认时区和语言环境获得一个日历import java.util.Date;public class yinhang {  private String acount;     //账户  private String name;   //姓名  private String time;   //时间  

day33 序列类型,绑定方法,类方法,静态方法,封装继承和多态

Python之路,Day20 = 序列类型,绑定方法,类方法,静态方法,封装继承和多态 序列是指有序的队列,重点在"有序". 一.Python中序列的分类 Python中的序列主要以下几种类型: 3种基本序列类型(Basic Sequence Types):list.tuple.range 专门处理文本的附加序列类型(Text Sequence Types):str 专门处理二进制数据的附加序列类型(Binary Sequence Types): bytes.bytearray.mem

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)最近进行数据库操作,遇到一个问题,就是大量删除一个数据表中的数据后,由于设定了id是自增的,导致再插入时,默认生成的id会很大,这个时候想要再次插入新的数据,应该怎么办呢?1.明确目前最后一个id的大小select id from tags order by id DESC limit 0,1; 假设返回的是9,则设置数据表从10开始自增 2.修改这个数据表从10开始自增alter table tags auto_increme

Java类集(接口继承的关系)

类集的概念: 类集(Collection)就是一个动态的对象数组,与一般的对象数组不同,类集中的对象内容可以任意扩充. 类集的特性: 这种框架是高性能的 框架必须允许不同类型的类集以相同的方式和高度互操作方式工作 类集必须是容易扩展和/或修改的 Java类集(接口继承的关系)

Java学习笔记-4.继承与多态

一.继承机制 1.继承:允许一个类作为另一个类的扩充版本 2.单继承:一个类只继承了一个父类    多继承:一个类继承了多个父类 Java只支持单继承,C++支持多继承 二.类的继承 1.形式: class SubClass extends BaseClass { //子类类体,定义子类的新成员 } Java中所有的类都直接或间接地继承类 java.lang.Object 2.构造方法 (1)显式构造方法    形式:super(参数表); 系统执行到这条语句时,会根据参数表判断调用父类中哪个构

面向对象:封装继承和多态、接口

1.多态 定义:不同对象对于同一个方法(Cut)调用表现出不同行为多态性主要是靠重写和隐藏来实现 a.(父类引用指向子类对象)b.(父类类型做参数,传递子类对象)自定义方法参数是父类类型 传递的实参是子类对象c.(父类类型作返回类型,return子类对象)自定义方法的返回类型是父类类型,return是类对象注:都是把子类对象赋给父类类型 举例: 添加乐器类using System;using System.Collections.Generic;using System.Linq;using S

C++之封装继承和多态

C++中非常重要的概念,尤其是相对于C语言而言,也是其具有如此高的工程使用性的重要原因. 封装 所谓封装是将某些东西隐藏起来,让外界无法直接使用,而必须通过某些特定的方式才能访问.也即是,将抽象得到的数据和行为(类似于属性和方法)结合构成一个有机整体,将数据与操作数据的函数构成类,其中数据和函数都是类的成员. 其目的是将对象的使用者和设计者隔离开来,提高软件的可维护性和可修改性,使用者不必了解具体的实现细节而只是通过外部接口及特定的访问权限使用类成员,从而增强了安全性且简化了编程,也使得不同类之