标签:
主要知识点:
面向对象:把数据和对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过信息进行通信。程序流程由用户在使用中决定。面向过程:自顶向下顺序执行,逐步求精,其程序的结构按功能划分若干个模块,这些模块形成一个树状的结构,各模块之间的关系尽可能的简单,在功能上相对独立;每一个模块都是由顺序,选择和循环三种基本结构来组成;其模块化的具体方法是使用子程序。程序流程在写程序中就已决定。
面向对象的特点:
类是java语言最小的变成单位,也是设计和实现java程序的基础。
类是一组事物共性的特征和功能的描述,类是一组事物的总体描述,是按照面向对象技术设置的最小单位,也是组成项目的最基本的模块。类的概念是抽象的,类似于建筑设计中的图纸,是对于实现需要代表的具体内容的抽象,类只包含框架结构,而不包含具体的数据。所以类代表的是总体,不是代表某个特定的个体。
类是抽象的,对象是具体的。
构造方法:用来构造类的实例(每一个类都默认有一个无参的构造方法,得使用new调用)
字段:类或对象所包含的数据,对类状态的一种描述。
方法:类或对象的特征或行为。
作用:给类中的字段进行初始化,可以用来创建对象。
特点:1.方法名和类名相同,不用定义返回值,不需要写return语句。
注意:多个构造方法是以重载的形式出现的。
static是一个修饰符,用于修饰成员(成员变量和成员函数)。
特点:
弊端:
什么定义静态的成员呢?或者说,在定义成员的时候,到底要不要被静态修饰?
成员变量。(数据共享的时候静态化)
该成员变量的数据是否是所有对象一样:
如果是,那么该变量需要被静态修饰,因为是共享数据。
如果不是,那么就说这是对象的特有数据。
成员函数。(方法中没有调用特有数据的时候就定义成静态)
该函数内是否访问了特有数据。
如果有不能被修饰,没有则需要被静态修饰。
成员变量和静态变量的区别?
所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。
静态的注意:静态的生命周期很长。
静态代码块:就是一个有静态关键字标示的一个代码块区域,定义在类中。
作用:可以完成类的初始化,静态代码块随着类的加载而执行,而且只执行一次(new 多个对象就只执行一次)。
如果和主函数在同一个类中,优先于主函数执行。
静态代码块,构造代码块和构造函数的区别?
静态代码块:用于给类初始化,类加载时会被加载执行,只加载一次。
构造代码块:用于给对象初始换,只要创建对象该不菲就会被执行,且优先于构造函数。
构造函数:给对应对象初始化,建立对象时,选择相应的构造函数初始化对象。
创建对象时,三者被加载执行顺序:静态代码块>构造代码块>构造函数
什么时候会加载类?
使用类中的内容时加载:有三种情况。
1.创建对象,new StaticCode();
2.使用类中的静态成员 StaticCode.num = 9 ,StaticCode.show();
3.在命令行中运行 java StaticCodeDemo
类所有内容加载顺序和内存中的存放位置
利用语句分析
Person p = new Person("zhangsan",20);
该句话所做的事情:
1.在栈内存中,开辟main函数空间,建立main函数的变量p
2.加载类文件:因为new要用到Person.class,所有要先从硬盘中找到Person.class类文件,并加载到内存中。
加载类文件时,除了非静态成员变量(对象的特有属性)不会被加载,其他的都会被加载。
记住:加载,是将类文件中的一行行内容加载到内存中,并不会执行任何的语句。加载时期,即使有输出语句也不会执行。
静态成员变量(类变量) ----------》方法区的静态部分
静态方法 ----------》方法区的静态部分
非静态方法(包括构造函数) ----------》方法区的非静态部分
静态代码块 -----------》方法区的静态部分
构造代码块 ----------》方法区的静态部分
注意:在Person.class文件加载时,静态方法和非静态方法都会加载到方法区中,只不过要调用非静态方法的时候要先实例化一个对象。
对象才能调用非静态的方法,如果让类中的所有非静态方法都随着对象的实例化而建立一次,那么会消耗大量的内存资源。
所以才会让所有的对象共享这些非静态方法,然后用this关键字指向调用非静态方法的对象。
3.执行类中的静态代码块,如果有的话对person.class进行初始化。
4.开辟空间:在堆内存中开辟空间,分配内存地址。
5.默认初始化:在堆内存中建立对象的特有属性,并进行默认的初始化。
6.显示初始化:对属性进行显示初始化。
7.构造代码块:执行类中的构造代码块,对对象进行构造代码块初始化。
8.构造函数初始化:对对象进行对应的构造函数初始化。
9.将内存地址赋值给栈内存中的变量p
p.setName("lisi");
1.在栈内存中开辟setName方法的空间,里面有:对象的引用this,临时变量name
2.将p赋值给this,this就指向了堆中调用该方法的对象。
3.将“lisi”赋值给临时变量name
4.将临时变量的值赋给this的name
Person.showCountry();
1.在栈内存中,开辟showCountry()方法的空间,里面有:类名的引用Person。
2.Person指向方法区中的Person类的静态方法区的地址。
3.调用静态方法区中的country,并输出。
注意:要想使用类中的成员,必须调用。通过什么调用?有:类名,this,super
1 class Person 2 { 3 private String name; 4 private int age=0; 5 private static String country="cn"; 6 Person(String name,int age) 7 { 8 this.name=name; 9 this.age=age; 10 } 11 static 12 { 13 System.out.println("静态代码块被执行"); 14 } 15 { System.out.println(name+"..."+age); } 16 public void setName(String name) 17 { 18 this.name=name; 19 } 20 public void speak() 21 { 22 System.out.println(this.name+"..."+this.age); 23 } 24 public static void showCountry() 25 { 26 System.out.println("country="+country); 27 } 28 } 29 class StaticDemo 30 { 31 static 32 { 33 System.out.println("StaticDemo 静态代码块1"); 34 } 35 public static void main(String[] args) 36 { 37 Person p=new Person("zhangsan",100); 38 p.setName("lisi"); 39 p.speak(); 40 Person.showCountry(); 41 } 42 static 43 { 44 System.out.println("StaticDemo 静态代码块2"); 45 } 46 }
输出结果:
StaticDemo 静态代码块1
StaticDemo 静态代码块2
静态代码块被执行
null...0 //构造代码块
lisi...100 //speak()
country=cn //showCountry()
特点:对方法或者对象只进行一次调用,可作为实际参数进行传递,只在堆里面开辟存储区域。只能使用一次,使用完就被销毁了。
new Person(); //表示匿名对象,没有名字的对象 new Person().age = 17; //使用一次之后就被销毁了
this :代表对象,就是所在函数和所属对象的引用。
this到底代表什么呢?
哪个对象调用了this所在的函数,this就代表哪个对象,就是哪个对象的引用。
开发时,什么时候使用this呢?
在定义功能时候,如果该功能内部使用到了调用该功能的函数,这时就用 this 来代表这个对象。
this还可以用于构造函数之间的调用。
注意:用this调用构造函数,必须定义在构造函数的第一行,因为构造函数是用于初始化的,所以初始化动作一定要执行,否则编译失败。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:将变化隔离,便于使用,提高重用性和安全性。
封装原则:将不需要对外提供的内容隐藏起来,把属性都隐藏,提供公共的方法对其访问。
封装机制在程序中的体现是:把描述字段的状态用字段表示,描述对象的行为用方法表示,把字段和方法定义到一个类中,并保证外界的字段不能任意的更改其内部的字段值,也不允许任意的调动其内部的功能方法。
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
好处:1.提高了代码的复用性。2.让类和类之间产生了关系,提供了另一个特征多态的前提。
父类的由来:其实是由多个类不断的向上抽取共性的内容而产生的。
java中只支持单继承,但是保留了这种多继承的机制,进行改良。
java为什么不支持多继承呢?
因为当一个类同时继承两个父类时,两个父类中有相同的功能,那么子类对象调用该功能的时候,运行哪一个呢?因为父类方法中存在方法体。
java支持多重继承,A继承B,B继承C,C继承D。
多重继承的出现,就有了继承体系,体系中的顶层父类是通过不断的向上抽取而来的,它里面定义了该体系最基本最共性内容的功能。
所以一个体系想要被使用,直接查阅该体系中顶层父类的功能就能知道该体系最基本的用法,那么想要使用一个体系的时候,需要建立对象。建议建立最子类的对象,因为最子 类不仅可以使用父类的功能,还可以使用子类特有的一些功能。
简单说,对于一个继承体系的使用,查阅顶层父类中的内容,创建最底层子类的对象。
子类实例化的过程
在继承操作中,对于子类对象实例化。子类对象在进行实例化之前必须首先调用父类的构造方法之后,在调用自己的构造方法。
子父类出现后,类中的成员有哪些特点:
1.成员变量
当子父类出现一样的属性时,子类类型的对象,调用该属性,值是子类的属性值。
如果想要调用父类中的属性值,需要使用一个关键字super()。
this 代表是本类类型的对象的引用。
super 代表子类所属父类中的内存空间的引用。
注意:子父类中通常是不会出现同名成员变量的,因为父类中只定义了,子类中就不用在定义了,直接继承过来就行。
2.成员函数
当子父类中出现一模一样的方法时,建立子类对象会运行子类中的方法,好像父类中的方法被覆盖掉一样。这个特性叫覆盖(复写,重写)
什么时候使用覆盖呢?当一个类的功能内容需要修改时,可以通过覆盖来实现,
3.构造函数
发现子类构造函数运行时,先运行了父类构造函数,为什么呢?
原因:子类的所有构造函数的第一行,其实都有一条隐身的语句super()
super()表示父类构造函数,并会调用于参数相对应的父类中的构造函数,而super()是在调用父类中空参数的构造函数。
为什么子类对象初始化的时候都需要调用父类的函数?
因为子类继承父类,会继承父类这中的数据,所以要看父类是如何对自己的数据进行初始化的,所以子类在进行初始化时,先调用父类构造函数。
注意:子类中所有的构造函数都会访问父类中空参数的构造函数,因为每一个子类的构造内第一行都有默认的语句super()。
如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super()语句指定要访问的父类中的构造函数。
如果子类构造函数中用this来指定调用自己的构造函数,那么被调用的构造函数一样会访问父类的空参构造函数。
问题:super()和this()是否可以同时出现在构造函数中?
两个语句都只能定义在第一行里,所以只能同时出现一个。
super()或者this()为什么一定要定义在第一行?
因为super()和this()都是调用构造函数,构造函数用于初始化,所以初始化动作要先完成。
继承的细节:
什么时候使用继承呢?
当类与类之间存在着所属关系时,才具备了继承的前提,a是b的一种,a继承b,狼是犬科中的一种,所属关系 “is a”。
注意:不仅仅是为了获取其他类中的已有成员进行继承。
判断所属关系,简单看,如果继承后,被继承中的类中的功能,都可以被子类所具备,那么继承成立,如果不是,不可以继承。
在方法覆盖时,要注意两点。
1.子类覆盖父类时,要必须保证,子类方法的权限必须大于等于父类方法的权限才可以继承,否则,编译失败。
2.覆盖时,要么都静态,要么都不静态。(静态只能覆盖静态,不静态只能覆盖不静态)
函数本身就具备多态性,某一种事物有不同的具体的体现。
体现:父类引用或者接口的引用指向了自己的子类对象。
多态的好处:提高了程序的扩展性。
多态的弊端:当父类引用指向子类对象时,虽然提高了扩展性,但是只能访问父类中的具体方法,不可以访问子类中的特有方法。
多态的前提:1.必须要有关系,比如继承或者实现。 2.通常会有覆盖操作。
多态是一种运行期的行为,不是一种编译期的行为。
编译时的类型由声明该变量时使用的类型决定,运行时的类型有实际赋给变量的对象决定,如果编译时的类型和运行时类型不同,就出现了多态。
实现多态的机制
父类的引用变量可以指向子类的实例对象,而程序调用的方法在运行时期才能动态的绑定,就是引用变量所指向真正实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
如果想用子类对象的特有方法,如何判断对象是哪个具体的子类类型呢?
可以通过一个关键字:instanceof //判断对象是否实现了指定的接口或继承了指定的类。
格式 <对象 instanceof 类型> ,判断一个对象是否所属于指定的类型。
Student instanceof Person = true;//student 继承了 person 类
标签:
原文地址:http://www.cnblogs.com/yanghyun/p/4300458.html