理解面向对象:
·面向对象是相对面向过程而言
·面向对象和面向过程都是一种思想
·面向过程强调的是功能行为
·面向对象是将功能封装进对象,强调具备了功能的对象
·面向对象是基于面向过程的
三个特征: 封装,继承,多态
成员变量和局部变量
作用范围:成员变量作用于整个类中,局部变量作用于函数中,或者语句中。
在内存中的位置:
成员变量在堆内存中,因为对象的存在,才在内存中存在。
局部变量:存在栈内存中。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
优点:·将变化隔离
·便于使用
·提高重用性
·提高安全性
封装原则:
·将不需要对外提供的内容都隐藏起来
·把属性都隐藏,提供公共方法对其访问。
构造函数:
特点:
1. 函数与类名相同
2. 不用定义返回值类型
3. 不可以写return
作用:给对象初始化。
注意:
1. 默认构造函数的特点
2. 多个构造函数是以重载的形式存在的。
构造代码块:单独的代码区域块{}
作用:给对象进行初始化,对象已建立就运行,而且优先于构造函数执行。定义的是不同对象共性的初始化内容。
和构造函数的区别:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
3. 构造函数见的调用只能用this,且只能放在第一行。因为初始化动作要先执行
This的用处:
1. 用于区分局部变量和成员变量
2. 用于构造函数间的调用。但只能放在第一行。
Static的用法: 是一个修饰符,用于修饰成员(成员变量,成员函数)
特点:
1. 随着类的加载而加载,随着类的消失而消失
2. 优先于对象的存在
3. 被所有对象所共享
4. 可以直接被类名所调用
实例变量和类变量的区别:
1. 存放位置:
类变量随着类的加载而存在于方法区中,实例变量随着对象的建立而存在于堆内存中。
2. 生命周期:
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。
注意事项:
1. 静态方法只能访问静态成员。
2. 静态方法中不可以定义this,super关键字。因为静态优先于对象存在。所以静态方法中不可以出现this。
使用static的情况:
1. 当对象中出现共享数据时,该数据可被静态所修饰。
2. 当功能内部只访问了静态的数据,那么该功能可以定义成静态函数。
将.Class文件发送给其他人,其他人只要用set classpath命令将该文件设置到相应的路径下,就可以使用该工具类,但是该类中到底定义了多少个方法,对方却不清楚,因为没有使用说明书。
Java的说明书制作:
第一步:在源程序中用/** */写好注释,类必须是public的。
第二部:用javadoc -d catalog demo.java 命令,catalog为要存放的目录,demo.java是要为之建立说明书的源程序。
静态代码块:
Static{
给类初始化
}
构造代码块:
{
给对象初始化
}
静态代码块的特点:
1. 随着类的加载而执行,且值执行一次。用于给类进行初始化
对象初始化过程:Person p = new Person(“zhangsan”,20);
1. 因为new用到了Person.class所以会先找到person.class文件并加载到内存中.
2. 执行该类中的static代码块,给Person.class类进行初始化
3. 在堆内存中开辟空间,分配内存地址
4. 在堆内存中建立对象的特有属性.并进行默认初始化.
5. 对属性进行显示初始化
6. 对对象进行构造代码块初始化
7. 对对象进行对应的构造函数初始化
8. 将内存的地址赋给栈内存中的p变量
函数覆盖:当子类出现和父类一模一样的函数时,子类对象调用该函数时,会运行子类函数内容,父类的函数被覆盖(重写)。
特性:当子类继承父类,沿袭了父类的功能,到子类中但是子类虽具备该功能,但是功能的内容却和父类不一致,这时就可以使用覆盖,保留父类的功能,并重写功能内容。
注意:
1. 子类覆盖父类,必须保证子类的权限大于等于父类权限,否则编译失败.
2. 静态方法只能覆盖静态方法.
class tel {
public void show() {
System.out.println("num");
}
}
class newtel extends tel {
public void show() {
super.show();
System.out.println("name");
System.out.println("place");
}
}
子父类中的构造函数:
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的的语句super.();而且子类中的构造函数默认第一行都是super();原因是父类中的数据子类可以直接获取,所以子类对象在 建立时,需要先查看父类是如何对这些数据进行初始化的。Super语句也必须放在构造函数的第一行。
Final关键字:
Final可以修饰类,方法,变量.
Final修饰的类不可以被继承
Final修饰的方法不可以被覆盖
Final修饰的变量是一个常量,只能被复赋值一次
内部类只能访问被final修饰的局部变量
抽象类的特点:
1. 抽象方法一定在抽象类中
2. 抽象方法和抽象类都必须被abstract关键字修饰
3. 抽象类不可以实例化
4. 抽象类中的方法要被使用,必须有子类复写其所有的抽象方法后,建立子类对象调用
模板方法模式:
abstract class Gettime {
public final void gettime() {
long start = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
public abstract void runcode();
}
class Subtime extends Gettime {
public void runcode() {
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}
接口定义格式:
1.接口中常见定义:常量,抽象方法.
2.接口中的成员都有固定的修饰符,常量:public static final;方法:public abstract.
3.接口中的成员都是public的
注意:
接口不能实例化,子类必须实现接口中全部的抽象方法才能实例化.否则子类是一个抽象类.
接口和接口之间可以多继承
多态:
1.多态的体现:
父类的引用指向了自己的子类对象
父类的引用也可以接收自己的子类对象.
2.多态的前提:
必须是类与类之间有关系,要么继承,要么实现
存在覆盖
3.多态的好处
大大提高了程序的扩展性
4.多态的弊端:
只能使用父类的引用访问父类中的成员
Instanceof判断所属类型
多态中成员函数的特点:
1. 在编译时期:参阅引用类型变量所属的类中是否有调用的方法.如果有,编译通过,如果没有,编译失败.
2. 在运行时期:参阅对象所属的类中是否有要调用的方法
3. 成员函数在多态调用时,编译看左边,运行看右边。
如Fu f = newZi();
多态中成员变量的特点:无论编译和运行,都参考左边(引用类型所属的类)
多态中,静态成员函数的特点:无论编译还是运行,都参考左边
内部类的访问规则:
1. 内部类可以直接访问外部类中的成员,包括私有;之所以可以访问外部类的成员是因为内部类中持有一个外部类的引用,格式为:外部类名.this;
2. 外部类要访问内部类必须建立内部类的对象.
3. 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类的对象格式为:
外部类名.内部类名 变量名=外部类对象.内部类对象
Outer.Innerin = new Outer().new Inner();
4. 当内部类定义在外部类的成员位置上,就可以被成员修饰符所修饰.比如:private:将内部类在外部类中进行封装
Static:内部类就具备static的特性.
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限.
在外部类中直接访问static内部类的非静态成员
NewOuter.Inner().function();
在外部类中,访问static内部类的静态成员
Outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的.
当外部类中的静态方法访问内部类时,内部类也必须是static的
内部类定义在局部时 ,不可以被成员修饰符修饰,可以直接访问类中的成员,因为还持有外部类中的引用.但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量.
匿名内部类:
1. 匿名内部类其实就是内部类的简写格式.
2. 定义匿名内部类的前提:内部类必须继承一个类或者实现接口.
3. 匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4. 其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,也可以理解为带内容的对象.
class Outer {
int x = 3;
public void function() {
new AbsDemo() { //匿名内部类
void show() {
System.out.print("x===" + x);
}
}.show();
}
}
abstract class AbsDemo {
abstract void show();
}