this关键字
看上去,是用于区*部变量和成员变量同名的情况。this为什么可以解决这个问题?this到底代表的是什么呢?this代表本类的对象,到底代表哪一个呢?this代表它所在函数所属对象的引用。简单的说,哪个对象在调用this所在的函数,this就代表哪个对象。
this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。换句话说,但凡是本类功能内部要用到本类对象时都是用this表示。构造函数间调用只能用this语句。this语句只能定义在构造函数内的第一行。
需求:给人定义一个用于比较年龄是否相同的功能,也就是是否为同龄人。代码示例:
class Person
{
private String name;
private int age;
Person(int age)
{
this.age = age;
}
public boolean compare(Person p)
{
return this.age == p.age;
}
}
class PersonThis
{
public static void main(String[] args)
{
Person p1 = new Person(22);
Person p2 = new Person(25);
boolean b = p1.compare(p2);
System.out.println(b);
}
}
static关键字
静态的意思。用于修饰成员(成员变量和成员函数)。
被修饰后的成员具备以下特点:
1.随着类的加载而加载。也就是说,静态会随着类的消失而消失,说明它的生命周期最长;
2.优先于对象存在。明确一点:静态是先存在对象是后存在的;
3.被所有对象所共享;
4.可以直接被类名调用;
使用注意:
1.静态方法只能访问静态成员;非静态方法既可以访问静态也可以访问非静态。
2.静态方法中不可以写this,super关键字。因为静态优先于非静态存在,所以静态方法中不可以出现this。
3.主函数是静态的。
当成员被静态修饰后就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。 类名.静态成员。
类变量和实例变量的区别:
1.存放位置不同:类变量随着类的加载而存在于方法区中。实例变量随着对象的建立而存在于堆内存中。
2.生命周期不同:类变量生命周期最长,随着类的消失而消失。实例变量生命周期随着对象的消失而消失。
静态有利有弊:
利处:对对象的共享数据进行单独空间的存储,可以节省空间。没有必要每一个对象都存储一份。可以直接被类名调用。弊端:生命周期过长,占用内存空间。访问出现局限性,静态虽好却只能访问静态的。
静态演示代码:
class Person
{
String name; //成员变量或实例变量。
static String country = "CN"; //静态的成员变量或类变量
public static void show()
{
System.out.print(name+":::"+country);
}
}
class StaticDemo
{
public static void main(String[] args)
{
Person p = new Person();
p.name ="lisi";
Person.show();
System.out.println(Person.country);
}
}
main 函数
主函数是一个特殊的函数。作为程序的入口可以被虚拟机所调用。public :代表着该函数的访问权限是最大的。 static :代表主函数随着类的加载就已经存在了。void :代表主函数没有具体的返回值。main :不是关键字,却是一个特殊的单词,可以被jvm识别。(String[] args):是函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组。主函数的格式是固定的,可以被jvm识别。jvm在调用主函数时传入的是new String[0] 。
class MainDemo
{
public static void main(String[] args)//new String[]
{
String[] arr = {"hah","hhe","heihei","xixi","hiahia"};
MainTest.main(arr);
}
}
什么时候使用静态?要从两方面下手,因为静态修饰的内容有成员变量和成员函数。
1.什么时候定义静态变量(类变量)呢?当对象中出现共享数据的时候,该数据就需要被静态所修饰。对象中的特有数据要定义成非静态变量(实例变量)存在于堆内存中。
2.什么时候定义静态函数呢?如果定义了一个功能是非静态的,但是这个功能内部没有访问到非静态数据(对象的特有数据)的时候,那么该功能可以定义成静态的。
一个类中会默认有一个空参数的构造函数,这个默认的构造函数的权限和所属类的权限一致。如果类被public修饰,那么默认的构造函数也带public修饰符。如果类没有被public修饰,那么默认的构造函数也没有被public修饰。也就是说,默认的构造函数的权限是随着类权限的变化而变化的。
将ArrayTool.class文件发送给其他人,其他人只要将该文件设置到classpath路径下就可以使用该工具类。但是,该类中到底定义了多少个方法对方并不清楚。因为该类并没有使用说明书。开始制作程序的说明文档,java的说明书通过文档注释来完成。制作程序说明书的类必须是被public修饰类。在DOS命令行里输入:javadoc -d 存放的位置 -author -version ArrayTool.java 命令进行编译程序说明文档。
静态代码块:格式:static{大括号里面是静态代码块里的执行语句} 特点:随着类的加载而执行,只执行一次且优先于主函数执行。 作用:用于给类进行初始化。 静态代码块只能访问静态成员,不能访问非静态成员。
静态代码块演示:
class StaticCode
{
int num = 9;
StaticCode()
{
System.out.println("b");
}
static
{
System.out.println("a");
}
{
System.out.println("c"+this.num);
}
StaticCode(int x)
{
System.out.println("d");
}
public static void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
static
{
System.out.println("b");
}
public static void main(String[] args)
{
new StaticCode(4);
}
}
对象的初始化过程:
Person p = new Person("zhangsan",10); 该句代码一执行都做了哪些事情呢 ?1.因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。
2.执行该类中的static代码块,如果有的话给Person.class类进行初始化。 3.在堆内存中开辟空间,分配内存地址。
4.在堆内存中建立对象的特有属性并进行默认初始化。 5.对属性进行显示初始化。 6.对对象进行构造代码块初始化。
7.对对象进行对应的构造函数初始化。 8.将内存地址赋给栈内存中的p变量。
设计模式:解决某一类问题最行之有效的方法。 java中有23种设计模式。
单例设计模式:
解决一个类在内存只存在一个对象。 思想:要保证对象唯一。
单例设计模式有两种体现:饿汉式和懒汉式。定义单例时建议使用饿汉式。
1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象。
2.为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
步骤:这三步怎么用代码体现呢?
1.将构造函数私有化。
2.在类中创建一个私有并静态本类对象。
3.提供一个公有并静态方法可以获取到该对象。
饿汉式单例设计模式:
class Single懒汉式单例设计模式:
{
private Single(){}
private static Single s = new Single();
public static Single getInstance()
{
return s;
}
}
class Single{private Single(){} private static Single s =null; //先不创建本类对象。public static Single getInstance() //调用方法的时候创建本类对象。{if(s==null){synchronized(Single.class){if (s==null)s = new Single();}}return s;}}懒汉式单例设计模式特点是实例的延迟加载,多线程访问时会出现安全问题,可以加同步解决,
用同步代码块和同步函数都可以解决,但稍微低效。用双重判断的形式能解决低效问题。
加同步使用的锁是该类所属的字节码文件对象。
对于事物该怎么描述还怎么描述,当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
继承:
好处:1.提高了代码的复用性。 2.让类与类之间产生关系,类之间有了关系才有了之后的多态。
extends 关键字,extends的作用是将两个类联系起来,使两个类之间有关系。
注意:类与类之间有所属关系才可以继承,不要为了获取其他类的功能简化代码而继承。java只支持单继承,不支持多继承。因为多继承容易带来安全隐患:当多个父类中定义了多个功能,但功能内容不同时,子类对象不确定要运行哪一个。
如何判断两个类之间是否有所属关系呢?如果搞不清楚那就先继承一下,看看子类是否全都具备父类中的内容,如果父类中有的内容子类中没有,那么两个类之间就不应该有继承。
java当中支持多层继承(继承体系)。那如何使用一个继承体系中的功能呢?
想要使用体系先查阅体系中父类的描述,因为父类中定义的是该体系*性的功能。通过了解共性功能就可以知道该体系的基本功能,这个体系就可以基本使用了。那么在具体调用时为什么要创建最子类的对象呢?1.因为有可能父类不能创建对象。2.创建子类对象可以使用更多的功能,包括基本的也包括特有的
简单一句话,查阅父类功能,创建子类对象使用功能。
继承代码示例:
class Person
{
String name;
int age;
}
class Student extends Person
{
void study()
{
System.out.println("good study");
}
}
class Worker extends Person
{
void work()
{
System.out.println("good work");
}
}
class ExtendsDemo
{
public static void main(String[] args)
{
Student s = new Student();
s.name = "zhagnsan";
}
}