黑马程序员_面向对象

来源:互联网 发布:mysql下载64位 编辑:程序博客网 时间:2024/04/19 06:16

对象

---------------------- android培训、java培训、期待与您交流! ----------------------

定义:也就是现实生活中的实体(实实在在存在的个体)包含属性和行为,

定义:对对象进行抽象,找出对象中存在的共性,用模型表示出来,也就是有了模型,就可以按照模型创建出对象。它是用来封装数据的

使用new 关键字来创建实例对象,一旦对象生成,就会被加载到堆内存中,内存图如下:

创建实例对象的内存图

内存储过程:

首先JVM调用main方法,并给予人口地址,在main方法中有一个局部变量,所以被存储在栈内存中,使用new关键字加上构造方法得到一个实例对象,此时被存储在堆内存中,而且会开辟一块内存空间存储两个成员变量,同时给予赋初始值,后面通过赋值将34zhangsan赋给两个成员变量。

注:如果创建了两个以上的对象,那么堆内存也会创建两个以上的存储区域。对象一旦没有地址指向,那么就会被当做垃圾。

 

成员:

在类中形成类的组成部分就叫成员

分类:

成员变量:类型用于表示状态的变量

成员函数:用于表示功能的方法

成员变量和局部变量的区别

1.       分配存储空间的时间不同,成员变量一开始就会产生存储空间,而局不变量要被使用的时候才分配存储空间

2.       成员变量时在类中定义,而局部变量时在方法中定义

3.       成员变量在整个类中都有效,而局部变量只能在区域块中有效。

4.       释放存储空间的时间不同,成员变量因为对象的消失而消失。局部变量因为区域块的结束而释放内存空间

5.       成员变量有默认初始值,而局部变量没有初始值。

封装

对对象的隐藏属性和实现细节,提高了安全性,复用性,提供其他方法进行对外开放。

例如:

Class Person

{

      Private int age;

      Privte String messege;

 Public void setAge(int age)

{

     This.age=age;

}

Public int getAge()

{

     return age;

}

Public void setMessge(String messege)

{

    This.messege.messge;

}

Public int getMessege()

{

    Return message;

}

 

}

匿名对象

使用new关键字创建的对象而没有名字,一般只使用于当对象对方法只调用一次的时候,还可以作为实际参数进行传递。

构造函数

一旦对象创建就会被构造函数进行初始化工作

1.       函数名必须与类名相同

2.       不能定义返回类型

3.       没有返回值

构造函数:就是不带参数的构造函数也称默认构造函数,只要类一创建,也会执行默认的构造函数,

如果该类中的成员都是静态的,所以该类就不需要创建对象为了保证不让其他成员创建该类对象,可以将构筑函数私有化。

 

构造函数与一般函数的区别

1.       只要对象一创建,那么就会调用对象所对应的构造函数,对对象进行初始化,而一般函数是对象调用的时候才能被初始化

2.       构造函数只能被调用一次,一般函数可以被调用多次

内存图

原理main方法进入了栈内存,在内存中有一个p局部变量,用new关键字创建了实例对象,在该对象中有两个成员变量,而且还有默认值,实例对象就会调用对应的构造函数,在构造函数中有两个局部变量,通过传值,把传过来的值赋给成员变量,赋完值后自动弹出栈外。

This

代表当前对象

就是所在函数所属对象的引用。

如果成员变量和局部变量重名是就可以使用this指定当前所属对象,还可以在构造方法中调用其他的构造方法。

注意:只能定义的构造函数中的第一行

内存图

Static

1.       在成员前加上static 关键字(修饰符),

2.       被修饰的成员作为对象共享

3.       优先于对象存在,static的成员随着类的加载就已经存在

4.       可以直接用类名调用

5.       static修饰的数据时共享数据,对象中的存储时特有数据

实例变量与静态变量的区别

1.       两个变量的生命周期不同,成员变量随着对象的创建而存在,随着对象的被回收而释放

2.       调用方式不同,成员变量只能被对象调用,静态变量可以被对象调用,也可以被类名调用

3.       别名不同,成员变量也称实例变量,静态变量称为类变量

4.       数据的存储位置不同,成员变量的数据存在堆内存中,静态变量数存储在方法区(数据共享区)的静态区。

静态使用的注意事项

1.       静态方法只能访问静态成员,(非静态即可以访问静态,有可以访问非静态)

2.       静态方法中不可以使用this或者super关键字。

3.       主函数是静态的

为什么主函数有特别的规定格式

Public static void main(String[] args)

主函数特殊之处:

1.       格式是固定的

2.       JVM所识别和调用

Public :因为权限必须是最大的

Static: 不需要对象的,直接用主函数所属类名调用即可

Void:主函数没有具体的返回值,

Main:函数名,不是固定的,只是一个JVM的固定的名字

String[] args:这时主函数的参数列表,是一个数字类型的参数,而且元素都是字符串类型

静态什么时候用

1.       静态变量

 当分析对象中所具备的成员变量的值都是相同的,则可静态修饰,只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的,如果是相同的时间,对象不需要做修改,只需要使用即可,不需要存储咋对象中,定义成静态的。

2.       函数是否用静态修饰,就参考有点,就是该函数功能是否有访问到对象中的特有数据,简单点说,从源代码看,该功能是否需要访问费静态的成员变量,如果需要,该功能就是非静态的,如果不需要,就可以将该功能成静态,担任,也可以定义成非静态,但是非静态要被调用,而仅成交对象,用非静态的,没有访问特有数据的方法,该对象的创建没有意义。

静态代码块

格式

Static

{

}

它是随着类的加载而执行,但只执行一次,

作用:用于给类进行初始化

构造代码块

格式

{

}

构造代码块可以给所有对象进行初始化

构造函数

是给对应的对象针对性的初始化

局部代码块,限定局部变量的生命周期

静态内存图解

/*

staticDemo2.java

*/

class Person

{

       private String name;

       private int age;

       static String country = "CN";

       public Person(String name,int age)

       {

              this.name = name;

              this.age = age;

       }

      

       public void show()

{

              System.out.println(Person.country+":"+this.name+":"+this.age);

       }

 

       public static void method()

       {

              System.out.println(Person.country);

       }

}

 

class StaticDemo2

{

       public static void main(String[] args) throws Exception

       {

              Thread.sleep(5000);

              Person.method();

 

              Person p = new Person("java",20);

              p.show();

       }

}                                          栈内存              堆内存

    

                                                       方法区

原理:1.java staticDeomo执行字节码文件,此时把staticDemo.classPerson.class加载到内存中,函数是存在方法区,静态是存在方法区中的静态区,JVM调用main函数,就从静态区中取出main函数到栈内存进行执行,直接用类名从静态区调用了静态函数methodmethod函数被取到栈内存,执行了输出语句,又调用静态区中的country静态变量,,执行完后弹出栈外,在main函数中有局部变量为p,用new关键字创建了实例对象,接着就在堆内存中开辟了一片存储空间,在堆内存中有两个成员变量,默认初始值为null0,,执行了构造函数,通过把值传给对象指定的成员变量,此时,堆中的成员变量被赋值,把堆中的地址赋给p变量,有用对象调用了方法区中的show函数,执行完毕后,弹出栈内存,最后,main函数结束运行,跳出栈,程序彻底完成。

単例的设计模式

对问题行之有效的解决方法,其实他是一只理想

1.       解决的问题:即使可以保证一个类在内存中的对象唯一性

2.       必须对于多个程序使用同一个配置信息对象时,就需要保证该对象的唯一性

如何保证对象的唯一性呢?

1.       不允许其他程序用new创建该对象。

2.       在该类中创建一个本类实例

3.       3对外提供一个方法让其他程序可以获取该对象。

步骤:

1.       私有化该类的构造函数

2.       通过New在本类中创建一个本类对象

3.       定义一个共有的方法,将创建的对象返回

例如:

单例的方式1:饿汉式

Class Single    //类一加载,对象就已经存在了

{

Private static singgle s=new Single();

Private Single(){}

Public static Single getInstance()

{

   Return s

}

}

単例的方式2:懒汉式

Class Single2   //l类加载进来,没有对象,只有调用了getIntance方法时,才创建对象,延//迟加载形式

{

   Private static Single s=null;

 Private Single2(){}

Public static Single2.getInstance()

{

     If(s==null)

        S=new Single2();

Return s;

}

}

Class SingleDemo

{

     Public static void main(Stirng[] args)

 

{

  Single ss=Single.getInstance();

}

}

                       内存图解

原理:

1.       java SingleDemo 执行该字节码文件,此时类被加载在内存中,

2.       JVM调用main方法,就从静态区中取到栈内存中执行,在main方法中有一个ss局部引用变量

3.       使用类名调用了方法区中的getInstance方法到栈内存,该方法返回s

4.       new关键字在堆内存中创建了一片存储对象的区域,此时生成了一个对象

5.       把该对象赋给了静态方法区中的s静态变量,

6.        getInstance返回s并赋给主函数中局部引用变量ss.,完成后弹出getInstance方法到栈外。

7.       最后main方法弹栈。程序结束。

 

继承

好处:1.提高了代码的复用性

    2.让类与类之间产生关系。实现了多态的向

 Java中支持单继承,不直接支持多继承,但对C++中的多继承机制进行改良。

但继承:一个子类只能有一个直接父类

多继承:一个子类可以有多个直接父类(java中不允许多继承)

不直接支持,因为多个父类中有相同成成员,会产生调用不确定性。最好的原因是父类的方法的实现具体功能不一样。所以不确定性。

java中是通过“多实现“的方式来体现

Java支持多层(多重)继承

当要使用一个继承体系时:

1.       查看该体系中的顶层类了解该体系的基本功能。

2.       创建体系中的最子类对象,完成功能的使用。

使用继承的弊端,打破了封装性

什么时候定义继承呢?

当类与类之间存在则所属关系的时候,就定义继承,zzzyyy中的一种,xxx extends yyy;

当子父类中的成员变量同名用super区分父类

This super的用法很相似

This:代表一个本类对象的引用

Super:代表一个父类空间。

当字符类中出现成员函数一模一样的情况,会允许子类的函数,

这钟现象,称为覆盖操作,这时函数在子父类中的特性。

函数两个特性:

1.       重载。同一个类中。

2.       覆盖,子类中,覆盖也称为重写,覆写。

覆盖的注意事项:

1.       子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。

2.       静态只能覆盖静态,或被静态覆盖。

什么时候使用覆盖操作?

当对一个类进行子类的扩展时,子类需要保留父类的功能声明,

但是要第一子类中该功能的特有内容时,就使用覆盖操作完成。

子类实例化过程

   子类定义的所有构造函数中都会默认调用父类中的无参构造函数。首先要从顶级类逐下初始化。

如果在子类中的构造函数使用this调用本类中的其他构造函数时,不会默认调用父类中的无参构造函数

Person p=new Person();

过程:

1.       JVM会读取指定的路径下的PersonClass文件,并加载进内存。并先加载Person的父类(如果有直接的父类的情况下)。

2.       在堆内存中开辟空间,分配地址。

3.       并在对象监控中,对对象中的属性进行默认初始化

4.       调用对应的构造函数进行初始化

5.       在构造函数中,第一行会先调用父类中构造购书进行初始化。

6.       父类初始好完毕后,在对子类的属性进行显示初始化。

7.       在进行子类构造函数的特定初始化

8.       初始化完毕后,将地址值赋给引用变量

Final

1.       final是一个修饰符,可以修饰类,方法,变量等。

2.       fianl修是的类不可以被继承的。

3.       fianl修饰的方法不可以被覆盖

4.       final修饰的遍历是一个常量,只能赋值一次。

为什么要用final修饰变量,其实在程序中如果一个数据时固定的,那么直接使用这个数据就可以了,但是这样阅读性差,所以它该数据起个名称,而且这个变量名称的值编译能变化,所以加上final固定

写法规范:常量所有字母都大写。如果出现多个单词,每个单词用下划线隔开。

抽象类

抽象:不具体的概念性。

特点:

1.       方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰

抽象方法必须定义在抽象类中,该类必须也被absract修饰

2.       抽象类不可以被实例化,为什么?因为调用抽象方法没意义

3.       抽象类必须由其子类覆盖了所有的抽象方法后,该子类才可以实例化,

否则,这个子类还是抽象类

1.       抽象类中有构造函数吗?

有,用于给子类对象进行初始化

2.       抽象类可以不定义抽象方法吗?

可以的,但是很少见,目的就是不让改类创建对象,AWT的适配器对象就是这钟类,通常这个类中的方法有方法体,但是却没有内容

3.       抽象关键字不可以和哪些关键字共存?

Private 如果使用private那么他的子类不知道有其方法,也不可以对外提供访问或者操作, 

static 因为抽象类要其子类实例化后才可以实现此功能,如果静态那么就属于类所以不可以。

  Final 是最终的意思,子类不可以继承,所以不能实现其函数功能。

4.       抽象类和一般类的异同点

相同点:

抽象类和一般类都是由来描述事物的,都在内部定义成员。

不同点:

1.       一般类有足够的信息描述事物,抽象类描述事物的信息不足

2.       一般类中不能定义抽象方法,只能定义非抽象方法,抽象类即可定义抽象也可以定义非抽象的

3.       一般类可以被实力化,抽象类不可以被实例化。

抽象类是父类吗?

是的,因为要其子类覆盖其方法才可以被实例化。

接口

当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用

另一种形式定义和表示,就是接口  interface.

定义接口格式

Interface  接口名

例如:

Interface momeriy

{           public static final date=5;

      Public abstract void read(); 

Public abstract void  write();

}

定义接口使用的关键字不是class,是interface

对于接口当中创建的成员,而且这些成员都有固定的修饰符

1.       全局变量:public static final

2.       抽象方法:public abstract

类与类之间是继承关系,类与接口直接是实现关系

接口不可以实例化

只能由实现了接口的子类并覆盖率接口中所有的程序方法后,该子类才可以实例化。否则,这个子类就是一个抽象类。

Class U implements meomery

{

        Public  void  read(){}

        Public  void  write(){}

}

接口中的常量可以用接口名 实现类名  对象名调用常量。

提示:

java中不直接支持多继承,因为和出现调用的不确定性。所以java将多继承机制进行改良,在java中变成了多实现。

一个类可以实现多个接口。

接口的程序避免了单继承的局限性。

接口与接口之间是继承关系,而且还可以多继承。

抽象类和接口的异同点

相同点:

都是不断向上抽取而来的。

不同点:

1.       抽象类需要被继承,而且只能单继承

接口需要被实现,而且可以多实现

2.       抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用费抽象方法

接口中只能定义抽象方法,必须由子类去实现

3.       抽象继承的继承,是is a 关系,在第一该体系的基本共性内容

接口的实现是like a关系,在第一体系额外功能

多态

父类或者接口的引用指向其子类的对象。

好处:提高了代码的扩展性,前期定义的代码可以使用后前的内容

弊端:前期定义的内容不能使用(调用)后期子类的特有内容

多态的前提:

1.       必须要有关系,继承,实现

2.       要有覆盖

注意:对于转型,自始自终都是子类对象在做着类型变化。

转型:

向上转型

让子类向上转型,转为父类类型。限制引用。

向下转型

让父类强制转换成子类类型,父类不能创建了对象再转为子类。

什么时候使用向上转型和什么时候使用向下转型

1.       当只是想使用子类中的共性就使用向上转型    父类  父类名=new子类();

2.       当要使用子类中的特有方法的时候就可以使用向下转型  子类 子类名=(子类)父类名;

Instanceof是用于判断对象的具体类型,只能用于引用数据类型。

通常在向下转型前用于健壮的判断

1.成员变量

编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。

运行时:参考引用型变量所属的二类中的是否有调用的成员变量,并运行该所属列中的而成员变量。

简单说:编译和运行都参考等号的左边。

2成员函数(非静态函数)

编译时:参考引用型变量所属的类中的是否有调用的成员函数,有,编译通过,没有,编译失败

运行时:参考的而是对象所属的类中是否有调用的函数

简单说:编译看左边,运行看右边

3.       静态函数

编译时:参考引用型变量所属的类中的是否有调用的静态函数

运行时:参考引用型变量所属的二类中的是否有调用的静态函数

简单说;编译和运行都看左边

其实对于静态方法,是不需要对象的。

内部类

内部类访问特点

1.       内部类可以直接访问外部类的成员

2.       外部类要访问内部类,必须建立内部类的对象。

 

什么时候用内部类

一般用于类的设计

分析事物是,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时就是还有的事物定义成内部类来描述。

如果内部内是静态的,那么该类就相当于外部类。

为什么内部类能直接访问外部类中成员呢?

那是因为内部类持有了外部类的引用,外部类名.this.

外部类可以存放在局部位置上

匿名内部类

就是内部类的简写格式

必须由前提:内部类必须继承或者实现一个外部类或者接口

匿名内部类:其实就是一个匿名子类对象

格式:new 父类or接口(){}

通常的使用场景之一:

当函数参数是接口类型时,而且接口中的方法不超过三个,可以用匿名内部类作为实际参数进行传递,

作用:分类管理文件

包的声明格式:

Package 包名;

总结:包与包之间的类进行访问,被访问的包中的类必须是public的,被访问的包中的列的方法也必须是public ..

导包的原则:用到哪个类,计导入哪个类。

Jar

Java的压缩包。

---------------------- android培训、java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima
原创粉丝点击