面向对象Java_Java面向对象

本文详细介绍了面向对象编程的基础概念,包括类、对象、封装、继承和多态等核心特性。通过实例展示了如何在Java中定义类、创建对象,并解释了类与对象之间的关系。此外,还探讨了面向对象设计原则,如单一职责原则、开放封闭原则等。最后,通过创建汽车类的例子,阐述了如何将现实世界的事物转换为Java代码。
摘要由CSDN通过智能技术生成

面向对象是一种编程思想,而不是一种方法或标准。它指导我们从现实世界中事物的客观存在出发,进行编程。

“面向对象”(英语:Object

Oriented,简称OO)是一种以事物为中心的编程思想。

面向对象程序设计(英语:Object-oriented

programming,缩写:OOP),是一种程序开发的方法。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

面向对象是相对于面向过程的(c则是一个典型的面向过程的语言),站在面向对象的角度去看问题,你则是对象的动作的指挥者。如果站在面向过程的角度去看问题,你则是动作的执行者。

强调的是功能行为,面向过程”是一种以过程为中心的编程思想。“面向过程”他们不支持丰富的“面向对象”特性(比如继承、多态),就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向过程在这一系列工作的执行中,强调的是工作的执行。

面对简单的软件程序,我们往往不需要考虑过多的设计,任何一个小的功能单元或模块,都可以按照一定的步骤去实现,这种 step by

step 的方式即为面向过程。

随着程序的复杂性提升,我们无法按步骤去描述并实现编码,所以面向过程已无法适应。加之考虑到代码的可读及复用性等,便有了对象的概念,以及面向对象的编程思想。

当然,还有面向组件、面向服务等设计思想,不在此讨论。

要知道,二者并不是非此即彼,而是相辅相成的。

面向对象思想要求我们从宏观上进行程序设计,抽象出一个个“对象”。而面向过程,则在微观上对“对象”内部进行具体的实现。

可以看出,面向对象最终还是离不开面向过程。

举例来说,需要编程实现绘制圆形、三角形、矩形。

面向过程实现:

drawCircle... //一坨绘制相关的代码,下同

drawTriangle

drawRect

面向对象实现:

//抽象出画笔对象

class Painter {

drawCircle(){

//上述面向过程实现,下同

}

drawTriangle(){}

drawRect(){}

}

//面向对象,使用画笔绘制

1. painter.drawCircle() //此处只需要调用对象的方法,下同

1. painter.drawTriangle()

2. painter.drawRect()

1:面向过程

1:查资料

2:电脑城砍价

3:被黑

4:痛苦归来

2:面向对象

1:找对象。老师

2:老师.砍价

3:老师.检测电脑

4:电脑成功购买

1:面向过程

1:自己动手做

2:买菜

3:洗菜

4:煮饭炒菜

5:很难吃,浪费时间

2:面向对象

1:找专业对象

2:餐馆.点餐

3:餐馆,做饭

4:饭好吃,节约时间,精力

1:求介绍,相亲,找现成的对象。(面向对象的思想先找有的对象,直接拿来使用)

2:不满意,没有对象,自己造一个。(sun没有提供,自己造对象)

Everything is

Object,在 Java 语言的世界中,万事万物皆对象。上面提到“从现实世界中客观存在的事物出发”,这里客观存在的事物,我们称之为“对象”。

在程序中,对象是程序的基本构成单元,是客观存在的事物的体现。一个对象通常由一组属性和对这组属性进行操作的若干服务(方法)构成。

说到面向对象,就不得不说其三大特性:封装、继承和多态。

下面简单说说自己的理解吧,就不再贴相关示例了,网上有很多优秀的例子。

封装是面向对象最基础的特性。在前面介绍对象时,提到“一个对象通常由一组属性和对这组属性进行操作的若干服务(方法)构成”,这里的构成体现的就是封装性。

封装,是指对外隐藏对象内部的属性和实现细节,只提供相应的接口和方法进行交互。一方面,外部只需专注于对象所提供的能力,而不用关心内部实现细节;另一方面,避免了外部随意修改或访问内部属性和方法,从而提升了程序的健壮性;同时,封装能提升代码的复用率。

封装是把对象的属性和操作结合为一个独立的整体,隐藏对象内部操作的实现,用户只需要通过其对外提供的方法来访问该对象,无需知道其内部实现细节。

隐藏内部实现细节,提供公共访问方式

类内部可以自由修改不影响其调用者

减少耦合度,提高安全性

继承指一个对象从另一个对象中获得属性和方法的过程,继承者称为子类,被继承者称为父类。继承使得子类对象拥有父类对象的全部属性与方法(非私有)。

关键点:

子类也可以被其他类继承成为父类;

父类可以拥有多个子类,但一个子类只能有一个父类。这一点与现实中父亲与孩子的关系是一致的;

Java 中任何类都是

java.lang.Object 的直接或间接子类;

子类不能继承父类中访问权限为

private 的成员变量和方法;

子类可以重写(override)父类的方法;

子类可以通过 super

关键字访问父类的成员变量、方法和构造器;

final

声明的类或方法,不能被继承或重写;

继承是一个对象获取另一个对象属性的过程,关键字为extends和implements。

1).

IS-A关系(一个对象所属于另一个对象):

方式一. 用extends来实现继承:

public class Animal{

public void eat(){

System.out.println("Animal eating...");

}

}

public class Mammal extends Animal{

public void eat(){

System.out.println("Mammal eating...");

}

}

public class Dog extends Mammal{

public void eat(){

System.out.println("Dog eating...");

}

}

方式二.

用implements来实现继承:

public interface Animal{

void eat();

}

public class Mammal extends Animal{

public void eat(){

System.out.println("Mammal eating...");

}

}

public class Dog extends Mammal{

public void eat(){

System.out.println("Dog eating...");

}

}

无论方式一还是方式二,我们都可以用instanceof关键字检查得出:Mammal是一个Animal(哺乳动物也是动物);Dog既是一个Mammal,也是一个Animal(狗既是哺乳动物也是动物)。

public class Test{

public static void main(String[] args) {

Mammal m = new Mammal();

Dog d = new Dog();

System.out.print(m instanceof Animal);

System.out.print(d instanceof Mammal);

System.out.print(d instanceof Animal);

}

}

输出结果:

true true true

2).

HAS-A关系(一个对象含有另一个对象的一些属性):

public class Car{}

public class Speed{}

public class Benz extends Car{

private Speed sp;

}

Benz含有Spend属性,但Benz不是Spend

多态是在继承的基础上实现的,多态实现的三个必要条件:

继承

方法重写(override)

父类引用指向子类对象,例如:Human

human = new Man(),这里 Man extends Human。

当使用多态方式调用方法时,会依据以下规则:

首先检查父类中是否有该方法,如果没有,则编译错误;

若子类重写了该方法,调用子类的重写方法;

若子类没有重写该方法,则调用父类的方法;

多态的优点:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

实现多态的三个必要条件:继承、重写、父类引用指向子类对象。

1). 向上转型:

我们实例化一个Dog对象可以用 Dog d = new Dog(); 我们也可以用 Animal d = new

Dog();,后者就是向上转型(父引用指向子对象),上面两种方式创建出来的对象d,调用d.eat();输出的结果都是Dog

eating…,这就体现出了。

2). 举例说明:

class A {

public String show(D obj){

return ("A and D");

}

public String show(A obj){

return ("A and A");

}

}

class B extends A {

public String show(B obj){

return ("B and B");

}

public String show(A obj){

return ("B and A");

}

}

class C extends B {}

class D extends B {}

class Test {

public static void main(String[] args){

A a1 = new A();

A a2 = new B();

B b = new B();

C c = new C();

D d = new D();

System.out.println(a1.show(b)); //

System.out.println(a1.show(c)); //

System.out.println(a1.show(d)); //

System.out.println(a2.show(b)); //

System.out.println(a2.show(c)); //

System.out.println(a2.show(d)); //

System.out.println(b.show(b)); //

System.out.println(b.show(c)); //

System.out.println(b.show(d)); //

}

}

输出结果:

A and A //

A and A //

A and D //

B and A //

B and A //

A and D //

B and B //

B and B //

A and D //

前三个比较简单不容易出错,看看下面几个:

:a2是A的引用指向B对象,向上转型创建的对象会遗失掉和父类不同的方法和变量,所以a2只能调用show(D obj)、show(A

obj)两个方法,所以a2.show(b)应该调用show(A obj)方法,B中重写了该方法,所以运行时JVM会调用B类中重写的show(A

obj)方法,所以输出B and A;

: 原理同;

:a2.show(d)应该调用show(D obj)方法,B中没有重写该方法所以调用的为A类中的该方法,所以输出为A and

D;

:b为B类对象,可调用A类中show(D obj)、B类中show(B obj)、B类中show(A

obj)方法,所以输出如上。

单一职责原则SRP(Single

Responsibility Principle)

类的功能要单一,不能包罗万象,跟杂货铺似的。

开放封闭原则OCP(Open-Close

Principle)

一个模块对于拓展是开放的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改,哼,一万个不乐意。

里式替换原则LSP(the Liskov

Substitution Principle LSP)

子类可以替换父类出现在父类能够出现的任何地方。比如你能代表你爸去你姥姥家干活。哈哈~~

依赖倒置原则DIP(the

Dependency Inversion Principle DIP)

高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。就是你出国要说你是中国人,而不能说你是哪个村子的。比如说中国人是抽象的,下面有具体的xx省,xx市,xx县。你要依赖的是抽象的中国人,而不是你是xx村的。

接口分离原则ISP(the

Interface Segregation Principle ISP)

设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多。

通过Java语言定义一个汽车类,并生产出汽车,有颜色,轮胎个数, 有运行的功能。

如何描述现实世界中的事物,描述该事物的属性和行为,汽车具有颜色和轮胎数的属性,具备运行的行为。

如何使用Java语言进行转换?

根据对应关系:

属性:类中的成员变量

行为:类中的成员函数

那么定义Java类就是定义一个类的成员。汽车类具备的成员是:颜色,轮胎数,运行方法。

Car类定义流程:

使用class 关键字 定义类,

class空格

类名。类名就是标识符,命名规则,单词的首字母大写,多个单词的首字母大写。注意:不是规定,但是最好遵守

类名后紧跟一对{}表示类的开始和结束。

汽车有轮胎数 int num;

不需要给num初始化值,因为汽车轮胎数不确定,有4,有6,有8。

有颜色 String color

什么使用String

例如定义颜色”红色”是字符串类型。

也不需要初始化值。

跑的行为(方法、函数) void

run(){}

方法中执行输出语句。syso(“跑啦。。。。”);

public class Car {

String color;// 成员变量

int num; // 成员变量

// 成员函数

void run() {

System.out.println(color + "的车,轮胎数:" + num + "个,跑起来了");

}

}

我们常说“物以类聚”,表达“

同类的东西聚在一起”。其实 Java 中的类也可以这么去理解:“物”即客观存在的“对象”,同类物体的特征描述,即为“类”。

上面是我的个人理解,用术语概括就是:类是客观事物的抽象,或者说是对现实生活中事物的一种描述(属性和行为)。

类可以看成是创建Java对象的模板。

[public][abstract|final]class<class_name>[extends<class_name>]

[implements<interface_name>]

{

//定义属性部分

;

;

;

//定义方法部分

function1();

function2();

function3();

}

上述语法中各关键字的描述如下。

public:表示“共有”的意思。如果使用 public 修饰,则可以被其他类和程序访问。每个 Java 程序的主类都必须是

public 类,作为公共工具供其他类和程序使用的类应定义为 public 类。

abstract:如果类被

abstract 修饰,则该类为抽象类,抽象类不能被实例化,但抽象类中可以有抽象方法(使用 abstract

修饰的方法)和具体方法(没有使用 abstract 修饰的方法)。继承该抽象类的所有子类都必须实现该抽象

类中的所有抽象方法(除非子类也是 抽象类)。

final:如果类被 final

修饰,则不允许被继承。

class:声明类的关键字。

class_name:类的名称。

extends:表示继承其他类。

implements:表示实现某些接口。

property_type:表示成员变量的类型。

property:表示成员变量名称。

function():表示成员方法名称。

注意:类名应该以下划线()或字母开头,最好以字母开头;第一个字母最好大写,如果类名由多个单词组成,则每个单词的首字母最好都大写;类名不能为

Java 中的关键字,例如 boolean、this、int

等;类名不能包含任何嵌入的空格或点号以及除了下划线()和美元符号($)字符之外的特殊字符。

通过下面一个简单的类来理解下Java中类的定义:

public class Dog{

String breed;

int age;

String color;

void barking(){

}

void hungry(){

}

void sleeping(){

}

}

类进行实例化可生成对象,所以,类的具体表现或者实例就是对象,而对象的抽象或者总概括就是类。

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

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

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

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

一个类可以拥有多个方法,在上面的例子中:barking()、hungry()和sleeping()都是Dog类的方法。

创建一个新的类,就是创建一个新的数据类型。实例化一个类,就是得到类的一个对象。因此,对象就是一组变量和相关方法的集合,其中变量表明对象的状态和属性,方法表明对象所具有的行为。定义一个类的步骤如下所述。

编写类的最外层框架,声明一个名称为

Person 的类。

public class Person

{

//类的主体

}

类中的数据和方法统称为类成员。其中,类的属性就是类的数据成员。通过在类的主体中定义变量来描述类所具有的特征(属性),这里声明的变量称为类的成员变量。

类的方法描述了类所具有的行为,是类的方法成员。可以简单地把方法理解为独立完成某个功能的单元模块。

下面来定义一个简单的 Person

类。

public class Person

{

private String name; // 姓名

private int age; // 年龄

public void teli()

{ //定义说话的方法

System.out.println(name+"今年"+age+"岁!");

}

}

如上述代码,在 Person

类中首先定义了两个属性,分别为 name 和 age,然后定义了一个名称为 tell() 的方法。

每个类都有构造方法。如果没有显式地为类定义构造方法,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" );

}

}

编译并运行上面的程序,会打印出下面的结果:

小狗的名字是 : 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" );

myPuppy.setAge( 2 );

myPuppy.getAge( );

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

}

}

编译并运行上面的程序,产生如下结果:

小狗的名字是 : tommy

小狗的年龄为 : 2

变量值 : 2

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

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

例如,下面的命令行将会命令编译器载入java_installation/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;

}

public void empDesignation(String empDesig){

designation = empDesig;

}

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);

}

}

程序都是从main方法开始执行。为了能运行这个程序,必须包含main方法并且创建一个实例对象。

下面给出EmployeeTest类,该类实例化2个 Employee 类的实例,并调用方法设置变量的值。

将下面的代码保存在

EmployeeTest.java文件中。

import java.io.*;

public class EmployeeTest{

public static void main(String[] args){

Employee empOne = new Employee("RUNOOB1");

Employee empTwo = new Employee("RUNOOB2");

// 调用这两个对象的成员方法

empOne.empAge(26);

empOne.empDesignation("高级程序员");

empOne.empSalary(1000);

empOne.printEmployee();

empTwo.empAge(21);

empTwo.empDesignation("菜鸟程序员");

empTwo.empSalary(500);

empTwo.printEmployee();

}

}

编译这两个文件并且运行

EmployeeTest 类,可以看到如下结果:

$ javac EmployeeTest.java

$ java EmployeeTest

名字:RUNOOB1

年龄:26

职位:高级程序员

薪水:1000.0

名字:RUNOOB2

年龄:21

职位:菜鸟程序员

薪水:500.0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值