一、面向对象的认知
Java是一门纯面向对象的语言(Object Orented Program,简称OOP),在面向对象的世界里,一切皆为对象,面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来设计程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。
就拿洗衣服来类比写程序,若用传统的方法来洗衣服,需要很多个步骤,拿盆、放水、放衣服、放洗衣粉,手搓、换水等等步骤,而且这些步骤的顺序大部分都不能乱,你不能不放水,直接搓衣服,也不能不放洗衣服之间洗衣服,那样的话都会导致我们的衣服洗不干净,所以传统的方式注重的是洗衣服的过程,不同的衣服,不同的洗法,少一个环节都不行,若按照这种方式来写代码,将来扩展或者维护起来会比较麻烦。
而我们用现在的方式洗衣服,就是拿洗衣机去洗,我们只需要把衣服和洗衣粉放进洗衣机里等机器洗完就可以了,我们不用管衣服是怎么洗、怎么干的,以面向对象的思想来类比,就是不关注洗衣服的过程,我们只需要把衣服和洗衣粉放进洗衣机里等机器洗完就可以了,在这个过程中有人、衣服、洗衣服、洗衣机四个对象,洗衣服这个过程就是通过这四个对象之间的交互来完成的,这样我们扩展和维护起来也方便,洗不同的衣服,只需要用洗衣机不同模式就可以了,对程序来说也一样。
二、类的定义与使用
我们使用关键字class来定义类,一个源文件只能存在一个主类(public class),而class声明的普通类可以存在多个,语法如下:

例如我们定义一个Dog类:

Dog类只是一个模板,没有具体的意义,该类的所有对象都具备的成员属性和成员方法(行为)定义在类中,不同对象的属性值和具体表现出来的行为都是不同的,所以要让这个类有意义我们就需要通过这个类产生对象,我们称之为类的实例化。
产生对象,我们需要用到关键字new,语法格式为:类名称 引用名称 = new 类名称();例如我们让上面这个Dog类实例化,代码如下:

在new后面跟的类名称(),是为了产生Dog对象,而产生Dog对象就需要调用构造方法,这个方法不需要你去写,在产生对象时会自动在class文件中生成,构造方法是为了给对象的属性做初始化操作,就是给对象的属性赋其属性的数据类型所对应的默认值。
而构造方法有四大特点:1.构造方法名字与类名称相同,无法自定义方法名称⒉.构造方法没有返回值类型声明,3.构造方法在创建对象时,由编译器自动调用,且只在对象产生时调用一次。4.若在定义类时,没有明确定义构造方法,则编译器会编译时生成默认的无参构造;若在类中定义了构造方法,则默认的无参构造就不再生成,示例如下:

构造方法是在产生对象时由编译器自动调用,为对象初始化服务,我们可以看看类的实例化中JVM在背后具体干的事情。
1.先捡测Dog这个类是否被加载到NM中,类加载是一个比较复杂的问题,简单理解就是Dog这个类是否已经被加载到内存中,没有就加载到VM中,否则就执行下一步,JVM运行起来可能会加载上万个类,也有很多类不是立即加载的。程序中可能会自定义非常多的类,这些类不是程序一启动就加载进来的,而是用谁再加载谁!
⒉执行关键字new,看到new就在堆上开辟空间。为对象在堆上开辟空间。到底开辟多大内存,就看这个类中成员属性的类型以及个数来定。
3.调用构造方法为每个成员属性赋初始值! =>构造方法就是在产生对象时给属性赋值的!
this关键字
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
this引用有四个特性,
1.this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2.this只能在"成员方法"中使用
3.在"成员方法"中,this只能引用当前对象,不能再引用其他对象
4.this是"成员方法"第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收
this可以修饰成员变量,语法为:this.成员变量名称,也可以修饰方法,语法为:this.方法名称,表示调用类中的成员方法,this还可以调用构造方法,语法为:this(参数);但构造方法的调用只能在构造方法之间才可以,且调用语句必须在构造方法首行,this还可以表示当前对象的引用,当前是通过哪个对象来调用的方法或属性,this就指代谁。
static关键字
static表示静态,与类相关,和具体的对象无关,所以当我们看到static关键字时,就知道这个属性或方法与对象无关了,当static修饰属性时,称之为类属性,静态属性,存放在JVM的方法区,通过这个类创造的所有对象都具有这个static修饰的属性,当static修饰方法时,称之为类方法,之接通过类名称调用,与对象无关。
static变量的初始化,构造方法一般初始化的都是成员属性,构造方法时产生对象时为对象初始化的,静态变量一般就地初始化或者在静态代码块中初始化,代码如下:

代码块
代码块的定义为:使用{}定义的一段代码称之为代码块,根据代码块出现的位置以及关键字的不同,分为以下4种代码块,1.普通代码块:直接定义在方法内部,不加人数修饰符定义的代码,可以解决变量重名问题,代码如下:

2.构造块:直接定义在类中,使用{}的代码块称之为构造块,代码如下:

值得注意的是,构造块是先于构造方法执行的,
3.静态块:一般用于初始化静态变量,特点为:静态代码块在类加载时执行一次,与具体产生对象无关,若有多个静态块,按照代码的书写顺序依次执行,代码如下:


主类中的静态代码块还会优先于主方法执行! main存在于主类中,要执行主方法首先得将主类加载到VM中,当主类一加载,主类中的静态块就会自动执行。
三、面向对象
面向对象的三大特性:封装,继承和多态。封装就是对外屏蔽类内部的一些实现细节,类的外部只能通过类提供的方法来操作类,封装强调的是保护和易用,例如上面说的洗衣机,我们不用管它怎么洗的衣服,只需要按下按键就可以了,Java中主要通过类和访问权限来实现封装;类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符,可见性从小到大依次为:priavte(私有权限,类内部可见)<default(包访问权限,包内部可见)<protected(继承权限)<public(公开的,所有对象可见)。
首先是private访问修饰符,它修饰的属性称为私有属性,这些属性只在当前类的内部可见,若我们想要在类的外部取得或者调用私有属性,就要用到getter和setter,例如我们建一个银行卡的类,类中有卡号,密码和余额三个成员变量,我们查询一下余额,修改一下密码,代码如下:

查询余额:


修改密码:


default包访问权限,这个关键字不需要写,权限修饰符什么都没写的,就是包权限,包其实就是电脑中的文件夹。若多个包下都存在同名的类,就要使用import导入某个包下的某个类,若要频繁的使用一个包下的若干类的话,就需要使用通配符导入,语法为:import java.包名.*;还有就是静态导入:import static ,就是将一个类的所有静态域导入到当前类中,当你使用别人写好的静态方法或属性时,就好像是在你在当前类中定义的一样。
包访问权限的可见性,当访问修饰符为包访问权限时,被修饰的对象只在当前包的内部可见,只有同级目录下的类之间可见,子包(子文件夹)都不可见。
我们开发中常见的JDK的包有6种,
1.java.lang:系统的基础开发包,String,Object,在JDK1.1后自动导入,无须显示使用import导入java.lang包。 2.java.util : java提供工具程序包。整个集合框架都在这个包下,ArrayList,Arrays都在这个包下
3.java.sql:数据库开发包,JDBC相关的类都在这个包下,通过Java和数据库进行交互
4.java.io : lO编程开发包,文件输入输出都在这个包下
5.java.net :网络编程开发包,Socket相关的类都在这个包下
6.java.lang.reflect : java的反射开发包,所有框架的基础都在于反射
继承
继承就是代码复用,增加整个程序的扩展性,继承的语法:使用extends表示继承父类,访问修饰符 class 子类名称 extends 父类 {};父类就是几个类的共性,子类就是各个类,要用继承就需要满足一个is - a原则,比如猫是个动物,狗是个动物。
父类和子类成员关系,1.父类和子类不存在同名的属性和方法,2.若父类和子类成员变量同名,则编译器就会采用就近匹配原则,当父类中存在private私有域,子类在继承父类时,私有域无法直接使用这种继承称为隐式继承,3.父类和子类方法之间的调用,也是就近匹配原则,优先访问子类的同名方法。当产生子类对象时,默认先调用父类的构造方法产生父类对象而后调用子类构造方法产生子类对象。
super关键字
表示直接从父类中寻找成员变量或成员方法,1.super修饰属性,表示直接寻找的父类的同名属性,2.super修饰方法,表示直接寻找的父类的同名方法,语法为:super.属性名/方法名。super也可以修饰构造方法,表示直接寻找的父类的构造方法,语法为super();但其必须在首行,所以它不能和this的构造方法调用一起用。
继承访问权限protected关键字
在不同包的具有继承关系的类之间可见。
Java的单继承局限:一个类只能使用extends直接继承一个父类,不允许多重继承,但允许多层继承,就是可以B继承A,C继承B,但C不能直接一次就A和B。
final关键字
final修饰的属性,称为常量,一旦被final修饰的变量成为常量,一旦初始化后,值不能改,对于基本类型来说,就是具体的数值,对于引用类型来说,就是引用类型的数值或地址,final还可以修饰方法和类,被final修饰的方法无法被重写/覆写,被修饰的类不能有子类,JDK中的String类就是final类。
类和类之间的关系:继承和组合,继承表示的是类之间的 is a关系,组合表示的是类之间的 has a关系,继承和组合都可以实现代码复用,到底使用继承还是组合,要根据具体场景来看类之间的关系。
多态
在Java中同样的一个方法/行为,经过不同的对象,表现出不同的行为,这样的现象就称为多态,例如同一台打印机可以打印出不同的颜色,但想要实现多态,必须同时满足以下三个条件,缺一不可,
1.多态的实现必须依赖继承,在继承体系下才有多态。只有在继承关系的类之间才有多态可言 2.子类必须要覆写父类中的方法
3.通过父类的引用调用子类重写的方法
例如猫和狗都是吃东西,调用的方法相同,但表现出不同的eat行为,如下:

方法重写,在有继承关系的类之间,子类定义了和父类处理权限不同以外,其他(方法名称,参数列表,返回值类型(向上转型除外))完全相同的方法称为子类重写了父类的方法,子类重写方法的权限 >= 父类方法,方法重写与方法重载基本是完全相反的东西,二者的区别如下:

方法重载是静态绑定,就是在编译时,编译器根据用户传参的不同决定到底调用的是哪个方法,而方法重写是动态绑定,编译时无法确定到底调用的是哪个对象的eat方法,只要在运行时,根据具体传入fun的对象,才能知道到底调用的是哪个对象的eat方法,即运行时才明确调用的是哪个方法。
向上转型
天然发生的向上转型,也是以后产生对象的主要使用方式,语法:父类名称 父类引用 = new 子类实例();1.到底通过这个父类引用能调用哪些属性和方法,看父类中有哪些属性和方法,父类引用决定了能调啥东西,2.至于调用的这个方法到底表现出什么行为,看到底new的是哪个子类对象。有了向上转型,无论有多少Animal子类,也不管是不是产生新的Animal子类,只要是Animal的子类,统一可以使用向上转型,通过共同的父类引用animal来指向不同的子类对象,fun只需要定义一次,产生新的子类,fun方法丝毫不影响。
向下转型
向下转型︰需要强制类型转换,要发生向下转型,必须先发生向上转型,否则会报错。属于将大类型强制转换为小类型语法∶子类名称 子类引用 = (子类名称) 父类引用;可以使用Java的 instanceof关键字来判断一个父类引用是否指向一个子类实例,语法︰引用名称 instanceof 类,返回布尔值。
以上就是我学习Java类和面向对象的总结,篇幅有限,很多关键字的代码就没贴出来,如果有错误地方,欢迎大家指正。
19万+

被折叠的 条评论
为什么被折叠?



