黑马程序员:毕向东java视频之面向对象篇一(三大特性)

一、理解面向对象

面向对象和面向过程都是一种思想,面向过程强调的是功能行为,面向对象是将功能封装进对象,强调具备了功能的对象

面向对象的三个特征:封装、继承、多态性

类和对象的关系:类就是对现实生活中实物的描述,对象就是这类事物实实在在存在的个体

匿名对象的使用情况:当对对象方法仅进行一次调用的时候或使用匿名对象作为实际参数进行传递

 二、封装

定义:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式

好处:将变化隔离,便于使用,提高重用性,提高安全性

封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问

为什么对外提供访问方式?因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高代码的健壮性

构造函数

特点:

1、函数名与类名相同

2、不用定义返回值类型

3、不可以写return语句

作用:给对象进行初始化

注意:默认构造函数的是个空函数,对个构造函数是以重载的形式存在的,一旦在类中显示定义了构造方法,无论定义了一个或多个,系统将不再提供缺省的无参构造方法,此时,如果在程序中使用缺省构造方法,则将出现编译错误

构造函数和一般函数在写法上不同,在运行上也有不同,构造函数是在对象一建立就运行,给对象初始化,而一般方法是对象调用才执行,给对象添加对象具备的功能,一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次

什么时候定义构造函数?当分析事物时,该事物存在具备一些特性或者行为那么将这些内容定义在构造函数中

构造代码块:给所有对象统一初始化,定义的是不同对象共性的初始化内容,对象一建立就运行,优先于构造函数运行,构造函数是给对应的对象初始化

this代表它所在函数所属对象的引用,还可用于构造函数之间的引用,如this();这时this语句只能定义在构造函数的第一行,因为初始化要先执行

static静态关键字:用于修饰成员变量和成员函数,当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类调用

特点:

1、随着类的加载而加载,随着类的消失而消失,说明它的生命周期最长

2、优先于对象存在

3、被所有对象所共享

4、可以直接被类名所调用

实例变量和类变量的区别:

1、存放位置:类变量随着类的加载而存在于方法区中,实例变量随着对象的建立而存在于堆内存中

2、生命周期:类变量生命周期最长,随着类的消失而消失,实例变量的生命周期随着对象的消失而消失

静态的使用注意对象:

1、静态方法只能访问静态成员,非静态方法既可以访问静态也可以访问非静态

2、静态方法不可以定义this,super关键字,因为静态优先于对象存在,所以静态不可以出现this

3、主函数是静态的

静态有利有弊

利:对对象的共享数据进行单独空间的存储,节省空间,没有必要每个对象中都存储一份,可以直接被类名调用

弊:生命周期过长,访问出现局限性,静态只能访问静态

主函数是固定格式的,jvm识别,传入的是new string[0]

什么时候使用静态:

当对象中出现共享数据时,该数据被静态所修饰,对象的特有数据要定义成非静态讯在于堆内存中

当功能内部没有访问到非静态数据(对象的特有数据);那么该功能可以定义成静态的

帮助文档的制作javadoc:java的说明书通过文档注释完成

类前加上

/**

功能描述

@author XXX

@version v1.1

*/


函数头加上

/**

功能描述

@param arr 接受一个int类型的数组(参数描述)

@return 描述

*/

javadoc -d 存储目录 -author -version Array.java


生成的index.html即为帮助文档


注意:生成文档的类必须为public类型

一个类中默认会有一个空参数的构造函数,这个默认的构造函数的权限和所属类一致,如果类被public修饰,那么默认的构造函数也带public修饰,默认构造函数的权限是随着累的变化而变化的

静态代码块:随着类的加载而执行,只执行一次,用于给类初始化,优先于构造代码块执行

对象初始化的过程

1、new用到了class,会先找到class文件并加载到内存中

2、执行该类中的static代码块,如果有的话,给class类进行初始化

3、在堆内存中开辟空间,分配内存地址

4、在堆内存中简历对象的特有属性,并进行默认初始化

5、对属性进行显示初始化

6、对对象进行构造代码块初始化

7、对对象进行相应的构造函数初始化

8、将内存地址付给栈内存中的p变量

单例设计模式:

定义:解决一个类在内存只存在一个对象

方法一:饿汉式:Single类一进内存,就已经创建好了对象

1、为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象

2、还为了让其他程序可以访问到该类对象,只好在被类中定义一个对象

3、为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式

代码体现:

1、将构造函数私有化 private Single(){}

2、在类中创建一个本类对象private static Single s = new Single()

3、提供一个方法可以获取到该对象

public static Single getInstance()

{

        return s;

}

获取对象方法:

Single ss = Single.getInstance();

方法二:懒汉式:对象是方法被调用时,才初始化,也叫做对象的延时加载

private static Single a = null;

private Single(){}

public static Single get Instance()

{

     if (s=null)

          s=new Single();

       return s;

}

开发一般用方法一,方法二有漏洞

改进:

private static Single a = null;

private Single(){}

public static Single get Instance()

{

     if (s=null)

     {

           synchronized(Single.class)

            {

                   if(s=null)

                         s=new Single();

            }

       }

       return s;

}

三、继承:类与类之间有所属关系is a

优点:

1、提高了代码的复用性

2、让类与类之间产生了关系,有了这个关系,才有了多态的特性

注意:java只支持单继承,不支持多继承,因为多继承容易引起安全隐患,当多个父类中定义了相同功能,但功能内容不同时,子类不确定应该使用哪个功能,但java保留这种机制,并用另一种体现形式来完成表示--多实现

java支持多层继承

如何使用一个继承体系中的功能?

先查阅体系父类的描述,因为父类中定义的是该体系的共性功能,通过了解共性功能,就可以知道该体系的基本功嫩

简单一句话:查阅父类功能,创建子类对象使用功能

事物之间另两种关系:聚集has a、聚合,组合

子父类的变量

如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this,子类要访问父类中的同名变量,用super,父类中的成员变量为private时,使用super调用变异会出错

子父类的函数

覆盖:

1、子类覆盖谷类,必须保证子类权限大于等于父类权限才可以覆盖,否则会编译失败

2、静态只能覆盖静态

子父类的构造函数

在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super();

super();会访问父类的空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();如果要访问父类指定的构造函数,可以通过手动定义super语句的方式指定

注意:super语句一定要定义在子类构造函数的第一行

子类中所有的构造函数,默认都会访问父类中空参数的构造函数,当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问的本类的构造函数,子类中至少有一个构造函数会访问父类中的构造函数

object是所有类的父类

final

1、可以修饰类,函数,变量

2、被final修饰的类不可以被继承,为了避免被继承,被子类复写功能

3、被final修饰的方法不可以被复写

4、被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,还可以修饰局部变量

5、内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量

常量的书写规范:所有字母大写,如果由多个单词构成,单词见用_链接

出现原因:继承打破了类的封装性

抽象类

多个类中出现相同功能,但是功能主体不同

abstract  void study();

  特点:

1、抽象方法一定在抽象类中

2、抽象方法和抽象类都必须被abstract关键字修饰

3、抽象类不可以用new创建对象,因为调用抽象方法没意义

4、抽象类中的方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用,如果子类只覆盖了部分抽象方法,那么该子类还是个抽象类

特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象


模板方法设计模式:

在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么而这时就将不确定的部分暴露出去,让子类去实现


接口:

初期理解可以认为是一个特殊的抽象类,当抽象类的方法都是抽象的,那么该类可以通过接口的形式来表示,

class用于定义类

interfaxe用于定义接口

接口定义格式特点:

1、接口中常见定义:常量、抽象方法

2、接口中的成员都有固定修饰符

常量:public static final

方法:public abstract

接口中的成员都是public的,固定修饰符没写,系统会自动给加上

接口不可以创建对象,因为有抽象方法,需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。因为接口的所有方法都是public的,所以子类重定义方法也得是pubilc的

interface是特殊的class,编译也会生成class。

接口可以被类多实现,也是对多继承不支持的转换形式,java支持多实现

class Test  extends Demo implements Inter,InterA

接口之间也可以继承,而且支持多继承,但是多个接口不可以定义参数和函数名相同,但是返回值不同的函数后被同一个类继承

接口特点:

1、接口的对外暴露的规则

2、接口是程序的功能扩展

3、接口可以用来多实现

4、类与接口之间是实现关系,而且类可以继承一个类的同时实现富哦个接口

5、接口与接口之间可以有多继承关系

四、多态性

1、多态的体现

父类的引用指向了自己的子类对象,父类的引用也可以接收自己的子类对象

2、多态的前提

必须是类与类之间有关系,要么继承,要么实现,通常还有一个前提,存在覆盖

3、多态的好处

多态的出现大大的提高程序的扩展性

4、多态的弊端

虽然提高了扩展性,但是只能使用父类的引用访问父类的成员

5、多态的应用

转型:

Aninal a =new cat();//类型提升,向上转型

如果想要调用猫的特有方法时,如何操作?

强制将父类的引用转成子类类型,向下转型

Cat c = (Cat) a;

c.catchMouse();

注意:千万不要出现这样的操作,就是将父类对象转成子类类型,我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被提升,多态自始至终都是子类对象在做变化。

判断某一引用对象究竟属于什么类型:if(a instanceof Cat)

多态 性示例:

[java] view plain copy
  1. /* 
  2. 基础班学生: 
  3. 学习,睡觉 
  4. 高级版学生: 
  5. 学习,睡觉 
  6. 可以将这两类事物进行抽取。 
  7. */  
  8. abstract class Student  
  9. {  
  10.     public abstract void study();  
  11.     public void sleep()  
  12.     {  
  13.         System.out.println("躺着睡");  
  14.     }  
  15. }  
  16.   
  17. class BaseStudent extends Student  
  18. {  
  19.     public void study()  
  20.     {  
  21.         System.out.println("base study");  
  22.     }  
  23.     public void sleep()  
  24.     {  
  25.         System.out.println("坐着睡");  
  26.     }  
  27. }  
  28.   
  29. class AdvStudent extends Student  
  30. {  
  31.     public void study()  
  32.     {  
  33.         System.out.println("adv study");  
  34.     }  
  35. }  
  36.   
  37. class DoStudent  
  38. {  
  39.     public void doSome(Student stu)  
  40.     {  
  41.         stu.study();  
  42.         stu.sleep();  
  43.     }  
  44. }  
  45.   
  46.   
  47. class DuoTaiDemo   
  48. {  
  49.     public static void main(String[] args)   
  50.     {  
  51.         DoStudent ds = new DoStudent();  
  52.         ds.doSome(new BaseStudent());  
  53.         ds.doSome(new AdvStudent());  
  54.     }  
  55.       
  56. }  

6、多态中成员的特点

在多态中成员函数的特点:

在编译时期,参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有,编译失败

在运行时期,参阅对象所属的类中是否有调用的方法、

简单总结就是:成员函数在多台调用时,编译看左边,运行看右边。

 在多态中,成员变量的特点:

无论编译和运行,都参考左边(引用型变量所属的类)

在多态中静态成员函数的特点:

无论编译和运行,都参考左边

实例二:(多态+接口)

[java] view plain copy
  1. /*需求 
  2. 电脑运行实例, 
  3. 电脑运行基于主板。 
  4. */  
  5.   
  6. interface  PCI  
  7. {  
  8.     public void open();  
  9.     public void close();  
  10. }  
  11.   
  12. class MainBoard  
  13. {  
  14.     public void run()  
  15.     {  
  16.         System.out.println("mainboard run");  
  17.     }  
  18.     public void usePCI(PCI p)//PCI p =new Netcard()//接口型引用指向自己的子类对象   
  19.     {  
  20.         if(p!=null)  
  21.         {  
  22.             p.open();  
  23.             p.close();  
  24.         }  
  25.     }  
  26. }  
  27.   
  28. class NetCard implements PCI  
  29. {  
  30.     public void open()  
  31.     {  
  32.         System.out.println("netcard open");  
  33.     }  
  34.     public void close()  
  35.     {  
  36.         System.out.println("netcard close");  
  37.     }  
  38. }  
  39.   
  40. class SoundCard implements PCI  
  41. {  
  42.     public void open()  
  43.     {  
  44.         System.out.println("SoundCard open");  
  45.     }  
  46.     public void close()  
  47.     {  
  48.         System.out.println("SoundCard close");  
  49.     }  
  50. }  
  51.   
  52. class DuoTaiDemo2   
  53. {  
  54.     public static void main(String[] args)   
  55.     {  
  56.         MainBoard mb =new MainBoard();  
  57.         mb.run();  
  58.         mb.usePCI(null);  
  59.         mb.usePCI(new NetCard());  
  60.         mb.usePCI(new SoundCard());  
  61.     }  
  62. }  

五、object类

1、equals(object obj)object类中已经提供了对对象是否相同的比较方法,如果自定义类中也有比较相同的功能,没有必要重新定义。只要沿袭父类中的功能,建立自己特有的比较内容即可,这就是覆盖

2、toString() 

对象转成string结果: 类名@地址的十六进制表示哈希值

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页