Java笔记系列(基于马士兵的课堂)(1)-面向对象

时间:2022-09-20 08:47:58

1.    面向对象的编程设计思想(第三章内容)


区别于面向过程的设计思想

   Java笔记系列(基于马士兵的课堂)(1)-面向对象    Java笔记系列(基于马士兵的课堂)(1)-面向对象    

Java笔记系列(基于马士兵的课堂)(1)-面向对象
面向对象,封装过程在对象的内部,合适的方法应该出现在合适的类里面,(张三的名字让张三写最合适,让李四写并不合适)让对象更了解自己的内部,调用对象来调用方法。首先考虑作用域中的对象,而不是考虑通过过程达到,再考虑对象,类应该有怎样的属性和方法,最后考虑作用域中对象与对象之间的关系,类与类之间的关系。

对象与类的关系

本质是面向类的编程,对象用计算机语言对问题的描述,对象通过属性(也可以叫成员变量)和方法来分别对应事物所具有的静态属性和动态属性。

就像脑子中抽象的一种事物所具有的特点(一类事物的抽象,拥有静态属性,动态属性来下定义,定义这个类)其中静态属性对应成员变量,动态属性对应方法。瓶子

对象(也可以叫实例)这一类事物具体的某一种特征的具体的某个东西叫做对象。某一个瓶子(谁谁的某个怎样的瓶子)

类可以衍生出多个对象,类可以认为是一个模板,其衍生出的对象应具有他的静态,动态属性。但由于对象的不同其在类中的特点都有,但取值不同,所以区别了每个对象,每个对象都有自己的属性,区别于其他对象不同的属性。

类与类之间的关系

对象与对象之间的关系

1,关系与关系(弱):关联关系(最不紧密)常用:一个类的方法是另外一个类的对象

2,继承关系(强):(一般和特殊)…是一种…说的通就是继承关系(球类运动员是一种运动员,球类运动员从运动员中继承,篮球运动员是一种球类运动员,篮球运动员又从球类运动员中继承)这种关系很有可能派生出一个继承树,一个类可以从多个类中继承,同时也可以被多个类继承,从多个节点中(基本的),衍生出多个(特殊的),与c++中的多重继承相关。

3,聚合关系(强):(整体和部分的关系)谁谁是谁谁的一部分,说通之后就是聚合关系。也可以细分为聚集关系和组合关系,聚集关系往往成员之间是可以分开的(一个部分的。。也属于别的整体),但组合关系中成员与整体之间往往是密不可分的(一个部分只属于某个整体)。

4,实现关系(父类与子类之间的关系):去…,用车,用…车,怎样去,继承子类,通过某种方法实现叫实现关系。

5,多态:以后介绍。

对象和类的分析。(方法:找名词)

例1:

Java笔记系列(基于马士兵的课堂)(1)-面向对象

分清名词是类,还是方法。

旅行社,机票,旅客,账簿,目录是类。

机票所具有的属性:价格,时间,班次
……机票所具有的方法:作废,显示价格,显示航班时间。

方法与所需目的有关才需要封装在此类里,否则并不需要封装。

Java与面向对象

必须先定义类才能有对象,对象是java的核心。

对象是静态属性(成员变量)动态属性(方法)的封装体。

就像写程序时,写public class 在这个class中写成员变量,和方法。

这个成员变量(属性)应该有他的类型。方法应该有返回值,也可以没有返回值。

定义好类之后,开始做一个类的对象出来,类名 对象名 new 类名

J2sdk本身提供了许多类供编程人员使用,编程人员本身也可以定义自己的类(string,system)

为什么使用面向对象

Reusebility可重复使用性,属性方法的复用(同时),extensibility可扩展性,可维护性…比面向过程高级,还有更高级的—面向组件的编程,component-orinted,向更高级的抽象(所有语言可以互相访问)

Java中的面向对象与内存

 

6,         class关键词(用class定义一个类)

成员变量(属性,class静态属性):声明—初始化(赋值)—用值

成员变量与局部变量区别:成员变量可以是java中的任何一种数据类型(包括基本类型和引用类型),其可以不初始化(也就是赋值),其有默认初始化。注意class与class之间同名属性,其实不一样。

引用类型(一小块内存指向一大块内存,指针,调用):除了8种基本类型之外所有都是引用类型—String s;(占两块内存,未初始化之前内存中装的是空值—null,与基本变量占一块内存不同)

              S = newString(“hello world”);(new出来的东西<对象>在heap
(堆内存动态分配内存的当不用时,就是垃圾垃圾收集器会回收)里)

Java笔记系列(基于马士兵的课堂)(1)-面向对象

所谓new就是在内存中命名一块空间,所有的引用类型全部是指针

变量(对象)对class的引用就是指针,类是静态的在代码区里,类的每个成员变量在每个类中都有不同的值(除了静态变量)。方法只有一份,执行的时候才占内存。

对象的创建和使用:

使用对象.成员变量(或来引用对象的成员变量)。

使用对象.方法

同一类的每个对象有不同的成员变量储存空间。

同一类的每个对象共享该类的方法。

内存中类和对象的关系

     Java笔记系列(基于马士兵的课堂)(1)-面向对象

局部变量c1,c2在steak里,引用class c时用c1.i使其指向heap里的new对象中的属性中的i。

构造函数(构造方法)

New + 构造方法  创建一个新的方法

必须和class名相同,不能有任何的返回值,不能写void

方法调用完成之后,占内存中所有局部变量占用内存消失(局部变量消失),对象不会消失(留在heap里),当没有定义构造函数时,编译器为类自动添加

类名(){}的构造函数(空的构造方法,默认自定义初值)

构造方法出现的问题:

加入void 构造方法变成普通方法,构造方法没有返回值

普通方法调用:引用名.方法名(穿值)

构造方法:类名 对象名=new 方法名();

约定俗成:

Class名大写,变量名方法名首字母小写,运用驼峰标示:如果名字由好几个单词构成,除了第一个词之外,其他的词都应该大写。

没有任何引用指向堆内存中的内存,垃圾收集器会收集它。

方法的重载

一个类中可以定义多个名字相同的方法,参数(类型)不同,根据参数输入类型可以调用不同的方法。重载与重名不同,尽管可能返回值有无不同但只要输入参数类型相同,方法名字相同,就是重名而并非重载。除了普通的方法以外,构造方法也可以构成重载。

对象的创建和使用

必须使用new关键字来穿件对象

对象.用成员变量或来引用对象的成员变量

使用对象引用.方法来调用对象的方法

同一类的每个对象有不同的成员变量储存空间

同一类的每个对象共享该类的方法

非静态的方法是针对每个对象进行调用(在没有static的情况下)

This一般出现在方法中,当对象进行使用时才决定this指的是谁,此前不一定,用于避免重名问题,此后this永远代表对象本身(在堆内存中),此后进行的一系列运算都是对象的值和变量类型。

Staticstatic声明的成员变量为静态成员变量,他是该类的成员变量,第一次使用时被初始化,对于该类的所有对象static只有一份(不向普通《非静态》成员变量,每个对象都有一份)。在data内存中一直存在无论是否有对象,没有对象也可以访问这个变量,用class名.静态变量名(注意字符串常量也在data中)与常量不同该静态变量可以改变

静态变量可以用于记对象数(基础类型不存在引用只有一块内存

       Static声明的所有方法为静态方法,静态方法中只能引用的东西。

Package和import:为了避免类的重名冲突。给包起名的方法:约定俗成—把公司的域名倒过来。(如com.bjsxt.java140)class必须位于正确目录下,如果想在另外一个类中使用该类,要写全这个名字。<该类源代码可能会产生影响>,

Import 域名(包裹).类名(或者*,其中的所有类都引进)

(提供类的包裹在java jrelib 运行时《rt》中)Java.lang提供java语言核心类如String,math,integer,System,thread.

Java.awat 包含了抽象窗口工具集,用来构建和管理应用程序的图形用户界面(gui)

Java.applet 包含了applet运行所需要的类

Java.net包含执行与网络想相关输出的类。

Java.io包含提供多种输入输出功能的类

Java.util包含一些实用工具,如定义系统特性,适用于日期日历相关的函数。

Jar -cvf用命令提示符可以生成jar包。

Classpath中设置jar包的位置设置进去就可以打开其中的所有的class文件。

继承和权限控制:

Public关键字,访问控制符,权限修饰符(private,default,protected,public)

继承:类的继承,extends关键字实现继承机制,通过继承子类拥有了基类(superclass)所有的成员变量和方法,java只允许单继承不允许多继承(只有一个爸爸),多重继承应有意义,多重接口可以解决。

继承在堆内存中显示为(子类中套有父类对象,以及类对象所有的成员变量),

所以子类比父类大,子类对象包含父类对象

访问控制通过访问修饰符来完成,访问修饰符可以修饰成员变量,成员方法

可以显示class名

Private (私有的)最严格的权限修饰符:只有在该class里可以访问,在其他class中无法访问

Default(默认权限,包权限):被修饰对象前无访问修饰符认为是default修饰,

同一个包里的其他类可以访问该方法或者成员变量

Public:在所有位置都可以访问。

Protected(受一定保护):除了类内部,同包,子类<子类不一定同包>也可以访问。

与private不同,子类索然继承值,但不能访问。

对于class的权限修饰只能用public或者default

      在继承时,子类必须重写父类的构造方法

重写方法不能使用比父类更严格的权限。

Super关键字,super来引用基类的对象,this是对当前的引用(指向当前对象),super是对当前对象中父类的的对象进行引用(指向当前对象中的父类对象)。

继承中的构造方法:

子类可以在自己的构造方法中使用super调用其父类的构造方法,用this调用本类的其他的构造方法。Super (参数);调用父类构造方法。This(参数);调用本类的构造方法。若调用了父类的构造方法,一定写在子类构造方法的第一行。

而且若有构造方法一定调用父类构造方法,若不调用,自动默认调用父类空值构造方法。

如果子类的构造方法没有调用父类的构造方法,系统默认调用父类构造方法中没有参数的构造方法。若不满足上述条件,则编译出错。

在new某个类的对象时,自动使用该类的构造方法。

具体见person package

Jdk提供的类——object

object:http://docs.oracle.com/javase/1.5.0/docs/api/index.html

object类中的常用方法

java由于不可以多继承,java提供了一个根基类,所有的类都要从这个类中继承

这个类就是object类。

Public class Person{}=public class Person extends object{}它是classroot。

object类中的常用方法之toString() 方法

返回值:String(代表对象的字符串)

描述当前信息的有关信息

在进行String类型与其他类型数据进行连接时自动调用该对象的toString()方法

转换非String类型变量变为String类型

toString 方法每个类都应该重写,注意返回值是String类型,默认toString返回值前面是类名后面是该类的阿西编码(可以找到类位置的16进制码)。

Hashcode(hashcodes table根据hashcode编码表可以在内存中找到某个对象

Object之 equals方法

Equals用来比较对象所包含的内容是否相同(若简单地比较路径<引用>)

两个对象首先不能为空,当两个对象都指向同一个对象,x==y才会返回true。

所以Equals方法也应该重写。重写时勿忘加static让其可以使用。

Jdk中date,string等类已经重写了equals方法(object.equals())。

Instanceof可以去对象的类型,从而比较是否相同或者输出。

对象转型(casting

分为两种类型——向上转型,向下转型(与int转short等相似)


一个父类的引用型变量可一指向其子类对象。

Java笔记系列(基于马士兵的课堂)(1)-面向对象

注意若父类类型转为子类类型(父类引用指向子类对象),只能访问父类的属性。比如animal类型a转换为dog——a=new dog(m,n),此时他变成了一只狗,但系统会认为他只是一只普通的animal。可以进行强制转换。

Dog d1=(dog)a;d1=a;


面向对象最核心机制:动态绑定(多态)(迟绑定)

Java笔记系列(基于马士兵的课堂)(1)-面向对象

在执行期间,而非编译期间,判断所引用对象的实际类型,来进行方法的引用。

运行之后是根据实际来判定方法调用,而非引用类型。动态绑定指的是,实际绑定的(new的是谁)用的就是谁的方法,而非简单的引用方法,所以叫动态绑定。

最核心内存分析:(见test4)<注意不能随便传值>

若重写了父类方法,在new对象时(子类套父类),在父类的内存里就有一个指针指向子类重写的方法。从而达到了空前的可扩展性。

多态的三个条件,1,要有继承2,要有重写3,父类引用指向子类对象(三个条件一旦满足)

实际中如果对某个对象引用父类方法,实际是哪类对象就引用那类的方法,而非父类的方法。

游戏物体的多态包装:

如飞机大战游戏。将子弹和敌方飞机定义为对象。将显示其图形的方法,定义为若这个对象是子弹则画出子弹的图形,如果是敌方飞机则定义为敌方飞机的类型(当然敌方飞机也分为好多种,可以构建其子类,敌方飞机1,敌方飞机2,敌方boss…)如果临时再加入一个新的类型的敌人,这种情况,首先继承敌人这个类,重写,父类中的Draw方法,系统根据对象运行方法,这里叫多态,给程序的可扩展性带来了极大的好处。

抽象类

Abstract修饰类叫抽象类,修饰方法叫抽象方法。父类中由于多态,自己的方法只需要定义,不需要运行,但父类本身并不知道自己的子类如何定义。

只有定义没有实现,叫抽象方法。当一个类含有抽象方法时,这个类也得定义为抽象类,abstractclass 类名。但此时不能再定义一个对象为这个类的对象,而且子类必须对这个抽象类进行方法重写。 此时这个抽象类必须被继承,且这个子类若也为抽象,一定循环下去,找到一个非抽象的子类重写这个方法。抽象类不能被实例化,抽象方法只要生命不需要实现。

Final关键字:  (只读,不写)

可以修饰变量,方法,类。Final的方法不能被重写,final的变量为常量(与static不同,static可以根据每个对象的属性进行改变但,final不可以。),final的类不能被继承。Final的形式参数在方法内部不能被改变(因为要传实参。)

如果传一只猫,这只猫只能指向一个内存。(如public final class math不能被继承或者重写)

接口(面向对象的最后一个概念)

由于java不能用多继承,只支持单继承,所以产生接口,接口可以帮助我们。

接口(interface):接口是一种特殊的抽象类。其中所有的方法都是抽象方法,不需要实现的,其中所有的成员变量都是具有public,static,final属性的。

定义它:

Public interface runner{

Publicstatic final int id=1;//蓝色可以不写,写不写前面的内容都是一样

Public void start();

Public void run();

Public void stop();

}

为什么要定义其所有成员变量为final:为了修正c++中多继承的易出错问题(当多个父类对象拥有相同成员变量时)。<其实这个变量并不属于这个类>

所有的方法都是abstract的所以,每个方法都不用考虑实现,只需考虑返回值(与子类有关),局部变量。

多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口,与继承类似,接口与实现存在多态性(父类与继承也存在多态性<动态绑定>)

定义java类的格式    clss<name>[extends<superclass>][ implements <interface>]

 在子类中,这些未实现的方法必须全部被实现。

,  比如接口(painter singer)与类(student teacher)。如果singer a=new teacher();则只能调用singer的方法,和其中的成员变量,其他看不到,但也可以将其强制转换。如teacher b=(teacher)a;

 接口与抽象类的不同主要在于成员变量,方法是否都是抽象方法。

 接口的进一步理解:

 interface Comparable

中写了怎样比较大小,什么样是大,什么样是小,这样在子类比较时,不用每一种类型比较大小的时候都写一个方法,无论怎样的类型,都只需要一个算法实现,达到了可扩展性。

同时接口之间可以相互继承,且不用实现父类接口。

两个接口中有两个名字相同的方法,一个子类同时实现这两个接口,若这两个方法的返回值相同,则重写时系统默认这两个方法被同一个方法重写,若返回值不同则无解。(若输入值不同则重写可以认为构成重载)

总结:内存分析很重要

对象和类,面向对象,class,new(引用,构造方法),方法重载,this,static,package&import,访问修饰符(private 成员变量只能看不能用),继承,重写,final,Object toString,Object equals,对象转型(向上转型,向下转型),多态(继承,重写,父类对象指向子类方法),abstract class,interface(implements)。