面向对象(类/对象/封装/继承/static/内存类加载)
>面向对象:万物皆对象;
>类和对象:
从代码的角度来说:类是代码的载体。
从逻辑角度来说:类是静态文件;对象是内存中的地址;
形象的来说,类就是一个模具,是用来生产对象的;对象是基于类产生的,只在内存中出现,不在文件中出现。
>类的基本语法:
类的基本构造:
访问修饰符(public) class 类名{
//类内能出现的东西:
/**
*1.属性/全局变量/成员/成员变量;
*2.方法:
* 访问修饰符(public) 返回值(void) 方法名(形式参数列表){
* 方法体代码;
* }
*3.构造方法;
*4.代码块;
*{ 代码块; }
*5.静态代码块;
*static{ 代码块; }
*6.类(内部类)、
*class InnerClass{ }
*/
//不能直接出现表达式;
}
>成员变量
生命周期:全局变量/局部变量;
全局变量默认有初始值;
其中,局部变量,初始不赋值,不用不报错,一用就报错;
>方法/函数
不严谨的说法(不考虑static):
在另外的类,或main方法中,要想调用一个类的方法或属性,先生成这个类的对象。
生成一个类的语法 new 类名();然后对象名.方法名();
>构造方法
1.没有返回值的标识符;
2.构造方法的名字和类名一定要相同;
3.不能人工调用,当类被实例化的时候自动调用;
注意的细节:
如果没有人为添加一个构造函数,那么jdk会添加一个默认的无形参,无执行体的空构造函数;
但是如果自己添加了有参的,jdk就不会添加默认构造;
4.使用:当想在一个类实例化的时候干一些事情,写在构造里;
注意:构造里不要开启线程,这样会导致this溢出或者说this逃逸;
>封装和隐藏
1.包:package;(其他语言如C# namespace/命名空间)
简单来说,包是用来划分类的,包名通常倒域名(com.公司名.项目名.模块名);
当想使用其他包中的类(简单名称)时,要使用import关键字进行导包;
如果使用类的全名称(带包名.类名的名称),无需导入;
其中package java.lang 包下的类,无需导入,直接就可以使用(比如System类,String类);
包名.* 包名点通配符的方式,是将包内所有的类导入;
2.访问修饰符;(继承补充)
private:只有本类能访问;
protected:当前包中的类随意访问,另外包中的子类随意访问;
不写:当前包中的类随意访问;
public:任何类都能随意访问;
3.JavaBean(领域对象/实体);
提供private类型的成员变量(成员变量私有化);
提供get/set方法;(注意!细节!get/set方法都是将成员变量名首字母大写,前面加上get/set)
this关键字:当前类对象;
>继承(java 中为单继承)
类A.类B.
当B继承了A: class B extends A
B就拥有了A中的可见的方法和属性;
细节:
1.实例化子类对象,父类(祖先)对象先被实例化.即当创建一个子类对象的时候,父类(祖先)先被构造,子类再去构造;
2.继承具有传递性;Java中一切的类,都是Object类的子类;不写的时候jvm默认会加上 extends Object;
3.子类方法如果和父类方法重名,称作方法的覆盖或override;重写后子类对象调用该方法,执行重写后的方法(子类的方法);
4.方法重写后如果想要调用父类的方法,使用super(当前类父类的对象) 关键字,super.方法名();
>数据类型转换(基本数据类型/抽象数据类型转换)
基本数据类型:
隐式:小的转大的;
强制:大的转小的;
抽象数据类型转换(类和类之间必须存在继承关系才能转换):
上诉造型:父类对象可以接受子类对象,无论如何都不会错;
向下转型(注意):将父类对象给子类接收时,一定要看清楚,这个父类对象当初是new的谁;
如果 father对象,就是new 的一个father 那么son接受之后,编译没事,运行时报错;
如果father对象,接受或者指向的那个对象就是new的一个son,只用用父类对象(引用)接收一下,再向下转回去,没有问题;
>instanceof 关键字
子类中的方法,有继承父类的(调用父类的),重写父类的(调用子类的),子类独有的(如果是父类对象接收的,转型前,就用到了instanceof关键字,避免类型转换错误)
A instanceof B;//它的作用是判断其左边对象是否为其右边类的实例,或者说判断A对象能不能由B这个类的对象所接收,返回值为Boolean;或者说判断A类是否B类或者B类的子类 对象;
从A这个对象,最初创建时new的那个类,及往上的祖先,当B类都符合时都为true;
>static修饰符(跟着类走)
1.能被static修饰的:方法,变量和内部类;
2.加了static意味着什么:
被static修饰的东西是属于类的;//用的时候,可以直接用 类名. 的方式进行调用, 当然对象也可以调用;
不被static修饰的东西是属于对象的;//用的时候需要先new对象, 对象名. 的方式调用;
注意:时间上的先后顺序,先有的类,再有的对象,所以类的东西(static修饰的)不能调用非static的东西;
普通的方法可以调用static的东西.
>栈内存和堆内存:栈很小,堆很大,java中的所有的操作时在栈中进行操作,栈中操作的数据都是放到堆中去保存;
当 Test t=new Test()时:
new Test();就是先在堆内存开辟一个空间,new出Test类的对象;
小t 在栈内存中,引用堆中的对象;
实例化对象实际有多个步骤:
类的验证;类的装载;类的解析;类的加载;类的实例化;
其中:Test t=new Test()是将下面两个步骤合二为一;
类的加载:意味着将这个类装载到内存,并不去产生它的对象;此时static类型的东西就已经能用了;
类的实例化:类加载后,创建它的对象;此时非static的东西才能用;
注意:在一个内存区域中,类是唯一的,而对象可以有多个;