java面向对象

面向对象

对象有以下特点:

对象具有属性和行为。

对象具有变化的状态。

对象具有唯一性。

对象都是某个类别的实例。

一切皆为对象,真实世界中的所有事物都可以视为对象。

面向对象程序设计有以下优点。

可重用性:代码重复使用,减少代码量,提高开发效率。下面介绍的面向对象的三大核心特性(继承、封装和多态)都围绕这个核心。

可扩展性:指新的功能可以很容易地加入到系统中来,便于软件的修改。

可管理性:能够将功能与数据结合,方便管理。

面向对象具有继承、封装和多态 3 个核心特性

程序中的继承性是指子类拥有父类的全部特征和行为,这是类之间的一种关系。Java 只支持单继承。

封装的目的在于保护信息,使用它的主要优点如下。

保护类中的信息,它可以阻止在外部定义的代码随意访问内部代码和数据。

隐藏细节信息,一些不需要程序员修改和使用的信息,比如取款机中的键盘,用户只需要知道按哪个键实现什么操作就可以,至于它内部是如何运行的,用户不需要知道。

有助于建立各个系统之间的松耦合关系,提高系统的独立性。当一个系统的实现方式发生变化时,只要它的接口不变,就不会影响其他系统的使用。例如 U 盘,不管里面的存储方式怎么改变,只要 U 盘上的 USB 接口不变,就不会影响用户的正常操作。

提高软件的复用率,降低成本。每个系统都是一个相对独立的整体,可以在不同的环境中得到使用。例如,一个 U 盘可以在多台电脑上使用。
Java 语言的基本封装单位是类。由于类的用途是封装复杂性,所以类的内部有隐藏实现复杂性的机制。Java 提供了私有和公有的访问模式,类的公有接口代表外部的用户应该知道或可以知道的每件东西,私有的方法数据只能通过该类的成员代码来访问,这就可以确保不会发生不希望的事情。

多态性允许一个接口被多个同类使用,弥补了单继承的不足。

多态性允许一个接口被多个同类使用,弥补了单继承的不足。

在Java中对象的状态就是属性,行为通过方法体现,即Java中的对象一般由属性和行为组成。

一、类与对象的创建

一个类可以包含以下类型变量:

局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。

成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。

类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。

构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

下面是一个构造方法示例:

public class Puppy{

 public Puppy(){

 } public Puppy(String name){ 

// 这个构造器仅有一个参数:name 

}

 }

创建对象

对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:

声明:声明一个对象,包括对象名称和对象类型。

实例化:使用关键字 new 来创建一个对象。

初始化:使用 new 创建对象时,会调用构造方法初始化对象。

下面是一个创建对象的例子:

public class Puppy{ 

public Puppy(String name){

 //这个构造器仅有一个参数:

name System.out.println("小狗的名字是 : " + name ); } 

public static void main(String[] args){

 // 下面的语句将创建一个Puppy对象

 Puppy myPuppy = new Puppy( "tommy" );

 }

 }

访问实例变量和方法

通过已创建的对象来访问成员变量和成员方法,如下所示:

/* 实例化对象 */

 Object referenceVariable = new Constructor();

/* 访问类中的变量 */

 referenceVariable.variableName;

 /* 访问类中的方法 */

 referenceVariable.methodName();

实例

下面的例子展示如何访问实例变量和调用成员方法:

public class Puppy{

 int puppyAge; public Puppy(String name){

 // 这个构造器仅有一个参数:name 

System.out.println("小狗的名字是 : " + name );

}

 public void setAge( int age ){

 puppyAge = age;

 }

 public int getAge( ){

 System.out.println("小狗的年龄为 : " + puppyAge );

 return puppyAge;

} public static void main(String[] args){ 

/* 创建对象 */ 

Puppy myPuppy = new Puppy( "tommy" );

 /* 通过方法来设定age */

 myPuppy.setAge( 2 );

/* 调用另一个方法获取age */

 myPuppy.getAge( );

 /*你也可以像下面这样访问成员变量 */ 

System.out.println("变量值 : " + myPuppy.puppyAge );

 }

 }

源文件声明规则

一个源文件中只能有一个 public 类

一个源文件可以有多个非 public 类

源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。

如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。

如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。

import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

Java 包

包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

import 语句

在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类

import java.io.*;

一个简单的例子

在该例子中,我创建两个类:Employee 和 EmployeeTest

首先打开文本编辑器,把下面的代码粘贴进去。注意将文件保存为 Employee.java。

Employee 类有四个成员变量:name、age、designation 和 salary。

import java.io.*;

public class Employee{ String name; int age;

String designation; double salary;

// Employee 类的构造器

 public Employee(String name){

 this.name = name;

 } 

// 设置age的值 

public void empAge(int empAge){ age = empAge; } 

/* 设置designation的值*/

 public void empDesignation(String empDesig){

 designation = empDesig;

 }

 /* 设置salary的值*/

 public void empSalary(double empSalary){

 salary = empSalary;

 }

 /* 打印信息 */

 public void printEmployee(){ 

System.out.println("名字:"+ name );

 System.out.println("年龄:" + age );

 System.out.println("职位:" + designation );

 System.out.println("薪水:" + salary);

}

 }

重写

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

实例如下:

class Animal{ public void move(){

 System.out.println("动物可以移动");

}

 }

 class Dog extends Animal{

 public void move(){ 

System.out.println("狗可以跑和走");

 }

 } 

public class TestDog{ public static void main(String args[]){ Animal a = new Animal();

 // Animal 对象 

Animal b = new Dog();

// Dog 对象

  1. move();

// 执行 Animal 类的方法 

  1. move();

//执行 Dog 类的方法

 } 

}

尽管 b 属于 Animal 类型,但是它运行的是 Dog 类的 move方法。

这是由于在编译阶段,只是检查参数的引用类型。

然而在运行时,Java 虚拟机(JVM)指定对象的类型并且运行该对象的方法。

因此在上面的例子中,之所以能编译成功,是因为 Animal 类中存在 move 方法,然而运行时,运行的是特定对象的方法。

以下例子:

class Animal{ 

public void move(){

 System.out.println("动物可以移动");

}

 } 

class Dog extends Animal{ 

public void move(){ System.out.println("狗可以跑和走");

 } 

public void bark(){

 System.out.println("狗可以吠叫");

 } 

}

 public class TestDog{ public static void main(String args[]){

 Animal a = new Animal();

// Animal 对象

 Animal b = new Dog();

 // Dog 对象 a.move();

// 执行 Animal 类的方法 

  1. move();

//执行 Dog 类的方法 

b.bark();

} 

}

该程序将抛出一个编译错误,因为b的引用类型Animal没有bark方法。

重写规则

参数列表与被重写方法的参数列表必须完全相同。

返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。

访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。

父类的成员方法只能被它的子类重写。

声明为 final 的方法不能被重写。

声明为 static 的方法不能被重写,但是能够被再次声明。

子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

构造方法不能被重写。

如果不能继承一个类,则不能重写该类的方法。

Super 关键字的使用

当需要在子类中调用父类的被重写方法时,要使用 super 关键字。

代码如下(示例):

class Animal{

   public void move(){

      System.out.println("动物可以移动");

   }

}

class Dog extends Animal{

   public void move(){

      super.move(); // 应用super类的方法

      System.out.println("狗可以跑和走");

   }

}

public class TestDog{

   public static void main(String args[]){

      Animal b = new Dog(); // Dog 对象

      b.move(); //执行 Dog类的方法

   }

}

重载

重载 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

实例

public class Overloading {

 public int test(){

 System.out.println("test1");

 return 1;

 } 

public void test(int a){

 System.out.println("test2");

 } 

//以下两个参数类型顺序不同 

public String test(int a,String s){

 System.out.println("test3");

 return "returntest3";

} 

public String test(String s,int a){

 System.out.println("test4");

 return "returntest4";

 }

 public static void main(String[] args){

 Overloading o = new Overloading();

 System.out.println(o.test());

 o.test(1);

System.out.println(o.test(1,"test3"));

System.out.println(o.test("test4",1));

 }

 }

重载规则

被重载的方法必须改变参数列表(参数个数或类型不一样);

被重载的方法可以改变返回类型;

被重载的方法可以改变访问修饰符;

被重载的方法可以声明新的或更广的检查异常;

方法能够在同一个类中或者在一个子类中被重载。

无法以返回值类型作为重载函数的区分标准。

重写与重载之间的区别

区别点

重载方法

重写方法

参数列表

可以修改

一定不能修改

返回类型

可以修改

一定不能修改

异常

可以修改

可以减少或删除,一定不能抛出新的或者更广的异常

访问

可以修改

可以降低限制

总结

方法的重写和重载是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。

方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载。

方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写。

方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值