- 面向对象就是一种常见的思想,符合人们的思考习惯;
- 面向对象的出现,将复杂的问题简单化;
- 面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者。
成员变量和局部变量的区别:
1,成员变量存在类中,整个类都可以访问
局部变量定义在函数,语句,局部代码中,只在所属的区域有效。
2,成员变量存在于堆内存的对象中。
局部变量存在于栈内存的方法中。
3,成员变量随着变量的创建而存在,随着对象的消失而消失;
局部变量随着所属区域的执行而存在,随着所属区域的结束而释放。
4,成员变量都有默认初始化值,
局部变量没有默认初始化值。
this
关键字
1、this
调用本类中的属性,也就是类中的成员变量;
2、this
调用本类中的其他方法;
3、this
调用本类中的其他构造方法,调用时要放在构造方法的首行
静态关键字static
:
静态变量:static
的主要目的就是创建独立于具体对象的域变量与方法。
随着类被加载时,static
所修饰的成员都被加载出来了。
static
变量并不是所在类的某个具体对象所有,而是该类的所有对象所共有的,静态变量既能被对象调用,也能直接拿类来调用;除此之外,静态变量不能引用非静态方法,原因正如前面描述静态加载时机中说的那样,加载静态的时候,非静态的变量、方法等还不存在。但是,非静态方法或类却能正常引用静态变量或方法。因为非静态总是在静态之后出现的。
静态方法:和静态变量一样,属于类所有,在类加载的同时执行,不属于某个具体的对象,所有对象均能调用
它们仅能调用其他的static
方法。
它们只能访问static
数据。
它们不能以任何方式引用this
或super
。
(静态方法一般用于工具类中,可以直接拿类名调用工具方法进行使用。)
静态类:一般一个普通类是不允许被声明为static
的,但是,在内部类中可以将其声明为static
的,这个时候,外部类可以直接调用内部类,因为static的内部类是在加载外部类的同时加载的,所以也就是说,并不要实例化外部类就能直接调用静态内部类。
public class BaseStatic {
static {
System.out.println("Load base static");
}
public BaseStatic(){
System.out.println("BaseStatic constructor");
}
static class BaseInnerClass{
static{
System.out.println("Base inner class static");
}
public BaseInnerClass(){
System.out.println("BaseInnerClass constructor");
}
}
}
public class StaticLoadOrderTest{
public static void main(String[] args) {
// TODO Auto-generated method stub
new BaseStatic.BaseInnerClass();
}
}
设计模式:对问题行之有效的解决方式,强调的是解决问题的思想。
1、单例设计模式:
解决的问题:保证一个类在内存中的对象唯一性。
1、不允许其他程序用new创建该类对象。
2、在该类创建一个本类实例。
3、对外提供一个方法让其他程序可以获取该对象。
步骤:
1、创建一个私有静态的实例对象;
2、私有化构造函数,防止其在外部创建新的对象;
3、对外开放一个静态的函数返回该实例,可以直接使用类名进行调用(static
关键字)。
//饿汉式,可以防止多线程并发时的问题
class Single
{
private static Single s = new Single();//封装/防止外部函数进行直接调用。
private Single(){}
public static Single getInstance()
{
return s;
}
}
//懒汉式,会延迟创建新的对象,调用方法时才会创建新对象
class Single2
{
private static Single2 s = null;
private Single2(){}
public static Single2 getInstance()
{
if(s == null)
s = new Single2();
return s;
}
}
面向对象的三大特性:
封装:
良好的封装能减少耦合型;
类内部的结构可以自由修改;
可以对成员进行更精确的控制;
隐藏信息和实现的细节。
继承:
类于类之间存在所属关系的时候,就会定义继承。
java 不直接支持多继承,因为多个父类中有相同成员时,会产生调用的不确定性。
- 成员变量:和父类同名时,需要用
super
区分。
super和
this`使用方法类似
this
是对本类对象的引用
super
代表一个父类空间。
成员函数:当子父类中出现同名时,会出现覆盖现象。
函数的两个特性(覆盖overload
和重载override
“在同一个类中”)。
覆盖的使用场景:当一个类进行子类的扩展时,子类需要保留父类的功能声明,但要定义子类特有功能时,需要使用覆盖。。
子类中:在实例化的过程中都会访问父类中空参数的构造函数。抽象类特点
abstract
:
1、方法只有声明没有实现时,该方法就是抽象方法,需要被abstract
修饰。抽象方法必须定义在抽象类中,该类必须也被abstract
修饰。
2、抽象类不能被实例化,因为抽象方法没有意义。
3、抽象类必须由其子类将所有抽象方法进行覆盖后,才能进行实例化。否则,该子类还是一个抽象类。
1、抽象类中有构造函数没?
有,用于给子类对象进行初始化。
2、抽象类可以不定义抽象方法吗?
可以,但是很少见,目的就是不让该类创建对象。AWT适配器就是这种类。
3、抽象类不可以和哪些关键字一起使用:
private
不行,不能覆盖
static
不行,
final
不行。
4、抽象类和一般类的异同点:
相同点:都是用来描述事物的,内部都定义了成员。
不同点:
a、一般类有足够的信息描述事物,抽象类描述事物的信息不足;
b、一般类不能定义抽象方法,抽象类可以定义一般方法;
c、一般类可以实例化,抽象类不能被实例化。
5、抽象类一定是一个父类吗?
是的。
- 当一个类中都是抽象方法时,可以定义接口,
interface
。
全局常量:public static final
抽象方法:public abstract
接口和类之间是实现的关系。。implements
接口不能直接实例化。
可以多实现。。
接口是对外暴露的规则
接口是程序的功能扩展
接口的出现降低程序的耦合性
接口可以用来多实现。
接口和接口之间可以有继承关系
接口和抽象类的异同:
相同点:都是不断向上抽取而来的。
不同点:1、抽象类需要被继承,而且只能单继承。
接口需要被实现,而且可以多实现。
2、抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
接口中只能定义抽象方法,必须有子类去实现。
3、抽象类的继承,是is a 的关系,在定义该体系的基本共性内容。
接口的实现是like a 的关系,在定义体系额外功能。
-
final
:继承的弊端:打破了封装性。
1、final是一个修饰符,可以修饰类、方法、变量;
2、final修饰的类不可以被继承;
3、final修饰的方法不可以被覆盖;
4、final修饰的变量是一个常量,不可以被再次赋值。
多态:
父类或接口的应用指向了子类的对象。。
多态的好处:提高了代码的扩展性和重复性;
多态的弊端:前期的定义内容不能使用后期的功能;
多态的前提:
1、必须要有关系继承,实现。
2、必须要有覆盖。
instanceof
用于判断具体类型,用于向下转型健壮性的判断多态时,成员的特点:
成员变量:编译运行都参考左边。
成员函数:编译看左边,运行看右边
静态函数:编译运行都看左边,静态时方法储存在静态区中,不需要对象,不直接使用类名调用就可以。内部类的访问特点:
1、内部类可以直接访问外部类的成员,
2、外部类需要创建对象来访问内部类的成员。
当分析事物中,发现事物内部还有事物,而且这个事物还访问描述事物内部的内容,这时候就需要内部类。
内部类在局部位置上只能访问final
修饰的变量
内部类必须实现接口或者继承父类。
-
匿名内部类:new 父类or接口(){ 子类内容}是一种简写格式
通常的使用场景之一是:当函数参数是接口类型时,而且接口中的方法不超过三个,可以用匿名内部类进行传递。
一个对象在实例化的过程
Person p = new Person();
1、jvm会读取指定路径下的Person.class文件,并加载进内存,并会加载Person的父类(如果有直接的父类的情况下),
2、在堆内存中开辟空间,分配地址;
3、并在对象空间中,对对象中的属性进行默认初始化;
4、调用对应的构造函数进行初始化;
5、在构造函数中,第一行会先调用父类中的构造函数进行初始化。
6、父类初始化完毕后,在风中子类的属性进行显示初始化;
7、再进行子类构造函数的特定初始化;
8、初始化完毕后,将地址值赋值给引用变量。