Java基础:面向对象

来源:互联网 发布:河北seo按效果付费 编辑:程序博客网 时间:2024/06/06 09:20

1.类和面向对象

面向对象是基于面向过程的,将功能封装进对象,强调具备了功能的对象;
初略的来说:
(1).面向对象的思想是一种符合人们思考的思想;
(2).可以将复杂的事情简单化;
(3).执行者到指挥者的转换;
(4).先要去找具有所需功能的对象来使用,如果没有满足条件的对象,就自己创建一个具有所需功能的对象,简化开发提高复用;
(5).进行Java开发的过程,其实就是不断的创建对象,使用对象,指挥对象完成功能,管理和维护对象之间的关系;
面向对象的三个特征:封装(encapsulation),继承(inheritance),多态(polymorphism);
类和对象的关系:对象是类的一个实例,对同一类事物抽取共性内容,对具体的抽象,定义在类中;
如何定义类:
(1).确定类的属性:确定成员变量;
(2).确定类的行为:确定成员方法;
实际在操作的过程中采用名词提炼法,还有一条经典的原则:谁拥有数据,谁就提供操作这些数据的方法;
成员变量和局部变量:
(1).成员变量作用于整个类中,有默认初始化值,存在于内存中的堆内存区域;
(2).局部变量作用于方法中,方法的方法,以及for循环等语句中,作用范围结束后即释放变量空间,没有默认初始化值,存在于内存中的栈内存区域中;
匿名对象:
(1).当对对象的方法仅进行一次使用的时候;
(2).匿名对象可以作为实际参数进行传递;
(3).匿名对象调用方法有意义,调用变量就没有什么实际意义;如果需要进行多个成员的调用,必须要对该匿名对象命名,便于操作;

2.封装

2.1 概念
封装是指隐藏对象的属性和实现细节,仅对外提供公共的访问方式;
2.2 封装的好处
(1).将变化隔离
(2).便于使用
(3).提高重用性
(4).提高安全性
2.3 封装的原则
(1).将不需要对外提供的内容都隐藏起来;
(2).把属性隐藏,提供公共的访问方式;
2.4 关键字private
private是一个权限修饰符,用于修饰成员(成员变量,成员函数,还可以是内部类),被私有化的成员只在本类有效;
私有仅仅是封装的一种表现形式;
常用方式:对于属性为提高安全性,用private修饰,然后提供公共的set和get方法来访问属性;

3.构造方法

3.1 构造方法的特点
(1).函数名和类名一样;
(2).不用定义返回值类型;
(3).不可以写return语句;
(4).可以被private修饰,表示不能在其他类中创建对象;
(5).多个构造方法是以重载的形式存在,通过参数列表来区分;
(6).当分析事物时,该事物具备一些特性或者行为,就将这些内容定义在构造函数中;
(7).默认构造方法的权限和所属的类的权限一致;
3.2 构造方法的作用:给对象进行初始化,对象一建立就会调用与之对应的构造方法,使用new创建对象时会调用构造方法;
3.3 默认的构造方法
当类中没有自定义构造方法时,在创建对象的时候,系统会默认执行一个默认的无参构造方法:类名(){ };
当类中自定义了构造方法后,就会去执行自己定义的构造方法,不会在去执行默认的构造方法;
这样的话,如果还需要使用无参的构造方法就必须显式的定义;
3.4 构造方法和普通方法
(1).在写法上有不同:构造方法名字同类名,没有返回类型,没有返回语句;
(2).在运行上有不同:
构造方法在对象建立时运行,给对象初始化,只运行一次;
普通方法在对象调用时运行,实现对象的功能,可运行多次;
3.5 构造代码块
(1).构造代码块的格式:大括号
{
需要执行的语句;
}
(2).构造代码块是用来对对象进行初始化的
(3).对象以建立,构造代码块就执行,而且优先于构造方法执行;
(4).构造函数和构造代码块的区别:构造代码块是对对象进行统一的初始化,构造函数是对对应的对象进行初始化;

4.关键字this

this关键字在代码上看,是用于区分局部变量和成员变量同名的情况;
this代表的是本类对象,代表它所在函数所属对象的引用,即那个对象在调用this所在的函数,this就代表那个对象;
this语句:
(1).用于构造函数之间进行的相互调用,eg:this();
(2).this语句只能定义在构造函数的第一行,因为初始化动作要先执行;

5.关键字static

5.1 static关键字概述
当所定义的内容是该类的对象需要共享的内容时,可以使用static修饰;
用于修饰成员,可以是成员变量,可以是成员方法;
被static修饰的成员不存在heap堆内存中,内存中只保留一份,被对象所共享;
被static修饰的成员多了一种访问方式,除了被对象调用,还可以直接被类名调用;
5.2 静态的特点
(1).随着类的加载而加载,生命周期最长,随类的消失而消失;
(2).优先于对象先存在;
(3).被所有对象共享;
(4).可以直接被类名所调用;
5.3 实例变量和类变量
(1).存放位置:类变量随类的加载存在于dataSegment,实例变量存在对对象的建立存在于堆内存中;
(2).生命周期:类变量随类的消失而消失,实例变量随对象的消失而消失;
5.4 静态使用注意事项:
(1).静态方法中只能访问静态成员,访问局限性;(无法从静态上下文中引用非静态成员);非静态方法既可以访问静态也可以访问非静态;
(2).静态方法中不能使用this/super关键字,静态优先于对象先存在;
(3).主函数main()是静态的;
5.5 静态的利弊
(1).好处:对共享数据进行单独空间的存储,节省内存空间,可以直接被类调用;
(2).弊处:生命周期太长,访问局限性;
5.6 静态的使用
(1).定义静态变量:当对象中出现共享数据时,该数据被静态锁修饰;对象中的特有数据要定义成非静态;
(2).定义静态方法:当功能内部没有访问到非静态数据(对象的特有数据),该方法可以定义为静态;
5.7 静态的应用
工具类,定义的方法都是静态方法,将类的构造方法私有化,将能隐藏的功能私有化;
5.8 静态代码块
(1).静态代码块的格式
static
{
要执行的语句;
}
(2).静态代码块随类的加载而执行,只执行一次,优先于main()方法,用来给类进行初始化;
特别注意的是语句: 类 对象 = null; //没有加载类

6.对象的初始化过程

对于创建对象的语句:类似:Person p = new Person("name", 23);
(1).new对象的时候用到了字节码文件Person.class,所以会先找到Person.class文件并加载到内存中;
(2).执行该类中的静态代码块,给类进行初始化;
(3).在堆内存中开辟空间,分配内存地址;
(4).在堆内存中建立对象的特有属性,并进行默认初始化;
(5).对属性进行显示初始化;
(6).对对象进行构造代码块初始化;
(7).对对象进行对应的构造方法初始化;
(8).将内存地址赋值给栈内存中的变量p;

7.继承

7.1 继承概述
继承是面向对象的一个重要特征,当多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需在定义这些属性和行为,只需要继承这个抽取出来的类就可以;使用关键字extends来说明继承关系;
7.2 继承的特点
(1).提高了代码的复用性;
(2).类与类之间产生关系,是面向对象具有多态的特性;子父类之间的关系是:子类 is  a  父类;
(3).Java中只支持单继承,不支持多继承,改良为多实现;
为什么不支持多继承:
因为多线程有安全隐患,当多个父类定义了相同的方法名时,方法的内容不相同,在子类中不能确定到底调用的是那个方法;
(4).Java中支持多层继承的继承体系,在开发使用时,查阅父类功能,创建子类对象使用功能;子类可以直接访问父类中的非私有成员;
为什么要创建子类对象:
1).有可能父类不能创建对象;
2).创建子类对象可以使用更多的功能,包括基本的也包括特有的;
7.3 继承出现后,类成员的特点:
(1).变量的特点
子类不能继承父类的私有变量;
当子父类中出现非私有的同名成员变量时,子类要访问本类中的变量使用this,子类中要访问父类中的同名变量使用super;
super的使用和this一致,两者够存在于方法去中,super表示父类对象的引用;
(2).方法的特点:覆盖
当子父类出现一模一样的方法时,当子类对象调用该函数,会运行子类函数的内容,如同父类的方法被覆盖了一样;
当子类继承父类,沿袭了父类的功能,但是子类虽具备该功能,但是功能的实现却不能满足需要,这时不用定义新功能,而是使用覆盖特性,保留父类的功能定义,重写功能内容;
子类同时具有父类方法的内容,可以使用super关键字调用父类中的方法;
注意:
1).子类覆盖父类,要保证子类权限大于等于父类权限;
2).静态只能覆盖静态;
3).父类中的私有方法不能被重写 ;
4).被final修饰的方法不能被重写;
区别重载和重写:
1).重载不要求有继承关系,只看同名函数的参数列表,包括参数的个数,序列,类型;
2).重写是子父类有继承关系或者实现关系,子父类的方法要一模一样;
(3).构造方法的特点
在对子类对象进行初始化时,父类的构造方法也会执行,那是因为在没有显式指定时,子类的每一个构造方法默认第一行有一条隐式的语句super();
为什么子类的构造函数要访问父类的构造函数?
因为父类中的数据子列可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对象初始化时要先访问父类的构造方法;
如果要访问父类中指定的构造方法,可以通过显示的super语句来指定,放在子类构造方法的第一行;
当然子类的构造函数第一行也有可能是this语句,子类中至少会有一个构造方法访问父类的构造函数;

8.关键字final

(1).可以修饰类,函数,变量;
(2).被final修饰的类不可以被继承,这样就可以避免继承被子类复写功能;
(3).被final修饰的方法不可以被复写;
(4).被final修饰的变量是一个常量只能被赋值一次,既可以修饰成员变量也可以修饰局部变量;
(5).内部类定义在类的局部位置上时,只能访问该局部被fianl修饰的局部变量;

9.抽象类

Java中可以定义没有方法体的方法,该方法的具体实现有子类完成,该方法成为抽象方法,包含抽象方法的类定义为抽象类;
抽象的由来:多个对象都具备相同的功能,但是功能具体实现有所不同,那么在向上抽取的过程中,只抽取功能的定义,并未抽取功能主体,那么只有功能声明,没有功能住的方法称为抽象方法;
抽象类的特点:
(1).抽象类和抽象方法必须用abstract关键字来修饰;
(2).抽象方法是有方法声明,没有方法体,定义在抽象类中;
(3).抽象类不可以被实例化,不能使用new创建对象;
(4).抽象类可以通过其子类实例化,而子类需要覆盖抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类;
(5).抽象类中可以有非抽象的方法;
抽象类和一般类:
(1).抽象类和一般类没有太大不同,该如何描述事物同一般类一致,只是描述的行为内容不确定,该行为是确定的,具体实现不确定,无法确定方法体,就用抽象表示;
(2).抽象类不一般类就多在有抽象方法;
(3).抽象类不能被实例化;
(4).抽象类虽然不能创建对象,但是也有构造方法,供子类实例化调用;
注意:
(1).被abstract修饰的方法不能同时被private,final,static修饰;
private:私有了就无法继承,更加不能被子类实现;
fianl:抽象父类中的方法被final修饰后就不能被复写;
static:静态可以被类名调用,但是类名调用抽象方法没有意义;
(2).抽象类中可以不定义抽象方法,这样可以不让本类实例化;

10.接口

10.1 概述
接口可以认为是一个特殊的抽象类,接口中的所有方法都是抽象的;接口的出现实现了:多继承-->多实现;
格式:
interface 接口名{ }
子类 implements 接口{ }
(1),接口中通产定义常量,和抽象方法;
(2).接口中的成员都有固定修饰符:都是public
常量:public static final
方法:public abstract
(3).在设计接口时,可以不添加修饰符,编译器会自动处理这些修饰符;
10.2 接口的特点
(1).接口是对外暴露的规则;
(2).接口是程序的功能扩展,基本功能定义在类中,扩展功能定义在接口中,由实现类实现;
(3).接口可以用来多实现;
(4).类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口;
(5).接口与接口之间可以是继承关系;
(6).接口的出现降低了事物之间的耦合性;
注意:
接口不可以创建对象,子类对接口中的抽象方法都覆盖后,才可以实例化;
实现多个接口时,接口中不可以有返回不同类型的同名抽象方法,子类实现时不能复写;
10.3 接口与抽象类
共性:都是不断向上抽取出来的抽象的内容;
区别:
(1).抽象类体现继承关系,一个类只能但继承;接口体现实现关系,一个类可以多实现,同时接口键有继承关系;
(2).抽象类中可以定义非抽象方法供之类直接使用;接口中的方法都是抽象的,成员有固定修饰符;
(3).抽象类可以私有变量或方法,接口中的常量和方法都是public修饰的权限;

11.多态

多态可以理解为事物存在的多种体现形态;
11.1 多态的体现
(1).父类引用指向了自己子类的对象;
(2).父类引用接受自己的子类对象;
11.2 多态的前提
(1).类与类之间必须有关系,要么继承,要么实现;
(2).存在覆盖,父类中有方法被子类重写;
11.3 多态的利弊
(1).提高了程序的可扩展性和后期可维护性;
(2).只能使用谷类中的引用访问父类的成员,父类性的引用在调用功能时会直接执行子类复写的方法但是不能直接调用子类中的特有方法;
如果需要使用子类中的特有方法,需要强制转换,向下转型;
11.4 多态的特点
(1).多态中非静态成员方法的特点
在编译期,参阅引用型变量所属的类中是否有调用的方法;如果有,编译成功;否则编译失败;
在运行期,参阅对象所属的类中是否有复写的方法;
编译看左边,运行看右边;
(2).多态中成员变量的特点
无论编译和运行,都参考左边,引用变量所属的类;
(3).多态中静态成员函数的特点
无论编译和运行,都参考左边;父类引用在调用静态同名函数时,被调用的是父类中的静态函数,
11.5 多态应用实例
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.zr.day08;   
  2. /*  
  3. 电脑的运行实例。电脑的运行由主板控制,假设主板只是提供电脑运行,但是没有上网,听歌等功能。而上网、听歌需要硬件的支持。而现在主板上没有网卡和声卡,这时可以定义一个规则,叫PCI,只要符合这个规则的网卡和声卡都可以在主板上使用,这样就降低了主板和网卡、声卡之间的耦合性。用程序体现。  
  4. */    
  5. // 接口PCI    
  6. interface PCI    
  7. {    
  8.     void open();    
  9.     void close();    
  10. }    
  11.     
  12. //网卡实现接口    
  13. class NetCard implements PCI    
  14. {    
  15.     public void open()    
  16.     {    
  17.         System.out.println("NetCard_open");    
  18.     }    
  19.         
  20.     public void close()    
  21.     {    
  22.         System.out.println("NetCard_close");    
  23.     }    
  24. }    
  25.     
  26. //声卡实现接口    
  27. class SoundCard implements PCI    
  28. {    
  29.     public void open()    
  30.     {    
  31.         System.out.println("SoundCard_open");    
  32.     }    
  33.     
  34.     public void close()    
  35.     {    
  36.         System.out.println("SoundCard_close");    
  37.     }    
  38. }    
  39.     
  40. class Mainboard    
  41. {    
  42.     //电脑运行    
  43.     public static void run()    
  44.     {    
  45.         System.out.println("Mainboard_run");    
  46.     }    
  47.         
  48.     //使用扩展功能    
  49.     public static void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。    
  50.     {    
  51.         if(!(p==null))    
  52.         {    
  53.             p.open();    
  54.             p.close();    
  55.         }    
  56.     }    
  57. }    
  58.     
  59. class Demo    
  60. {    
  61.     public static void main(String[] args)     
  62.     {    
  63.         Mainboard m =new Mainboard();    
  64.         //电脑运行    
  65.         m.run();    
  66.             
  67.         //  m.usePCI(null);    
  68.     
  69.         //电脑上网    
  70.         m.usePCI(new NetCard());    
  71.     
  72.         //电脑听歌    
  73.         m.usePCI(new SoundCard());    
  74.     }    
  75. }    


12.内部类

12.1 概述
将一个类定义在另一个类的里面,对立面那个类就称为内部类,或者叫内置类,嵌套类;
当描述事物时,事物的内部还有事物,该事物用内部类来描述;因为内部事务在使用外部事物的内容;
编译时,如果代码中有内部类,生成的class文件中会含有这样的文件:类$1.class ;编译器将会把内部类翻译成用$分割外部类名和内部类名的常规类文件;
12.2 内部类访问规则
(1).内部类可以直接访问外部类中的成员,包括私有;
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this;
(2).外部类要访问内部类,必须建立内部类对象;
12.3 访问格式
(1).当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象;
格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象;
eg:Outer.Inner in = new Outer().new Inner();
当内部类定义在外部类中的成员位置时,可以被成员修饰符修饰:
private:将内部类在外部类中进行封装;
static:内部类就具备static特性,出现访问局限,只能直接访问外部类中的static成员;
1).在外部其他类中,直接访问static内部类的非静态成员的格式;
new 外部类性.内部类名().方法名();
eg:new Outer.Inner().function();
2).在外部其他类中,直接访问static内部类中的静态成员格式;
外部类名.内部类名.方法名();
eg:Outer.Inner.function();
3).注意:
当内部类中定义了静态成员时,该内部类必须是static的;
当外部类中的静态方法访问内部类时,内部类也必须是static;
在实际引用中内部类通常被定义为private;

(2).内部类定义在局部位置时

内部类定义在外部类的某个方法中,创建了这个类型的对象,且仅使用了一次,那么可以在这个方法中定义局部;

1).不可以被成员修饰符修饰;它的作用域被限定在声明这个局部类的代码中;

2).可以直接访问外部类中的成员,因为还持有外部类中的引用;

3).内部类不可以访问它所在的具备中的非最终变量,只能访问被final修饰的局部变量;

12.4 匿名内部类

匿名内部类的一些特点:

(1).匿名内部类其实就是内部类的简写格式;

(2).定义内部类的前提:内部类必须是继承一个类或者实现接口;总有一个Object类;

(3).匿名内部类的格式:new 父类或者接口(){ 子类的内容  }

(4).匿名内部类就是一个匿名的子类对象;

匿名内部类的优缺点:

优点:简化书写;

缺点:

(1).不能直接调用自己的特有方法,相当于是一个子类对象赋值给了父类引用;

(2).不能作强制转换动作,都不知道子类是什么,怎么转;

(3).如果继承的父类或接口中要实现的方法有很多时,使用匿名内部类阅读性会非常差,而且调用和麻烦;

13.包

package:Java中的包就相当于文件系统中的文件夹,也是一种封装形式;
包的作用:
(1).为避免多个类重名的情况,如果出现两个相同名字的类,可通过包将两者区分,从而避免冲突;
(2).对类文件进行分类管理,可以将相关的一些类放在同一个包中;
(3).给类提供多层命名空间;
(4).包的出现可以将Java的类文件和原文件分离;
使用包的规则:
(1).包必须写在程序的第一行,因为要先有包,才知道类文件的存放地方;
(2).类的全称:包名.类名;
(3).编译定义了包的程序文件时,在编译时指定包的存储目录;格式:javac -d 目录 类文件.java
包之间的访问:
(1).要访问其他包中的类,需要定义类的全称:包名.类名;
(2).包如果不在当前路径,需要使用classpath设定环境变量;
(3).被访问的包中的类的权限必须是public;
(4).类中的成员权限:

 

public

protected

default

private

同一类中

可以

可以

可以

可以

同一包中

可以

可以

可以

不可以

子类

可以

可以

不可以

不可以

不同包中

可以

不可以

不可以

不可以

0 0
原创粉丝点击