一,代码块
1, 方法中的代码块
在方法中可以用{}的形式来定义一段代码,超出{}范围之后,{}中的变量就会自动销毁。
2, 类中的代码块
在类级别下用{}定义一段代码,它算是类的一个成员,当创建之后就会执行这段代码
静态的应用:
每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装;
***被修饰成员具备以下特点:
随着类的加载而加载;
优先于对象存在;
被所有对象所共享;
可以直接被类名调用;
静态缺点:
生命周期过长,占用内存;且静态方法只能访问静态,访问出现局限性
使用注意:
静态方法只能访问静态成员,非静态成员既可以访问非静态成员,也可以访问静态成员;
静态方法中不可以写this,super关键字;
主函数是静态函数;
静态存在于方法区;
Public static void main(String[] args)
其中,public:代表着该函数的访问权限是最大的;
Static:代表主函数随着类的加载就已经存在了;
Void:主函数没有具体返回值;
Main:不是关键字,是特殊的单词,被jvm识别;
(String[] args):函数的参数列表;参数类型是一个数组,该数组中的元素是字符串。
实例变量和类变量的区别:
String name;//成员变量(实例变量)。
static String country = "CN";//静态的成员变量(类变量)。
1,存放位置不同;
i. 类变量随着类的加载存在方法区中;
ii. 实例变量随着对象的加载而存在堆内存中;
2,生命周期不同;
类变量生命周期最长,随着类的消失而消失;
实例变量随着对象的消失而消失;
二,静态变量
1, 什么是静态变量:
用static修饰的变量就是静态变量,静态变量在类加载后就开始初始化,不用创建对象,可以直接使用;
静态变量可以使用“类名.变量名”进行访问,也可以使用“对象.变量名”进行访问,推荐使用前者;
静态变量被该类的所有对象所共享,就是该类所有对象都拥有这个变量;
2, 什么时候使用静态变量
当某个类所有对象都要使用一个数据时,这个数据就应该是静态的
三,静态方法
1, 什么是静态方法
静态方法可以在类加载后直接调用,不需要创建对象;
静态方法可以使用“类名.变量名”的形式进行访问,也可以使用“对象.变量名”的形式进行访问,推荐使用前者;
静态方法不能访问非静态成员,只能使用静态成员变量;因为非静态成员必须创建对象才能调用,而静态方法不需要创建对象就可以调用;
2, 什么时候使用静态方法
在定义方法时,如果这个方法不访问非静态成员,就可以定义为静态方法,这样别人使用方法时,无需创建对象,给调用者提供方便;
一个类无法创建对象时,通过静态方法获取对象;
四,静态代码块
1, 什么是静态代码块
静态代码块在类加载就执行;
静态代码块和静态方法相同,都是静态上下文不能访问外部非静态成员;
格式:
Static {
静态代码块中的执行语句;
}
特点:
随着类的加载而执行,只执行一次(类再次创建时不会执行),并优先于主函数;
用于给类进行初始化;
2, 什么时候使用静态代码块
在定义一个类的时候,如果希望别人一使用这个类,就执行一段代码,那么我们就把这段代码定义成静态代码块
//练习静态,静态代码块,说出打印结果;
classStaticBlock {
//静态代码块随着类的加载而执行,只执行一次,并优先于主函数;
static {
System.out.println("静态");
}
public static void main(String[] args) {
//newPeople().fun();
Peoplep1= new People();
p1.fun();
Peoplep2 = new People();
p2.fun();
}
}
class People {
static {
System.out.println("静态代码块");
}
//成员代码块有对象建立就运行一次;
{
System.out.println("成员代码块");
}
//构造函数,创建people()对象就执行一次;
public People() {
System.out.println("构造函数");
}
public static void fun() {
System.out.println("fun()");
}
}
//练习:打印顺序-----打印结果是B C A D
class Test7 {
public static void main(String[] args) {
newA(123);
//newA();
}
}
class A {
B b = new B();
{
b =new B(123);
}
public A() {
//给成员变量赋值,执行代码块
System.out.println("A");
}
public A(int x) {
this();//创建A(int x)对象;访问无参构造函数A();
System.out.println("D");
}
}
class B {
public B() {
System.out.println("B");
}
public B(int i) {
System.out.println("C");
}
}
五,单例设计模式;
设计模式:解决某类问题最行之有效的方法;java中有23种设计模式;
单例设计模式:解决一个类在内存中只存在一个对象;
当需要将事物的对象保证在内存中唯一时,就将使用单例设计模式,
例如:
classSingleDemo {
public static void main(String[] args) {
//创建对象s1 ,s2;
Singles1 = new Single();
Singles2 = new Single();
System.out.println(single1);
System.out.println(single1);
}
}
ClassSun {
private static Sun sun = new Sun();
// 2. 类内部创建一个对象,使用成员变量引用.用static修饰在类加载后初始化.防止类外修改加上private
privateSun() {
// 1. 私有化构造函数,阻止类外创建对象
}
publicstatic Sun getSun() {
// 3. 提供一个get方法获取对象,为了让类外直接使用加上static
return sun;
}
//...
//...
}
}
六,函数的参数传递:
1,基本数据类型:
基本数据类型直接存储在变量中,在调用函数的时候,函数中的实参也将记录住实参数据,函数中对形参改变,原调出的数据不变;
2, 引用数据类型
引用数据类型的变量中存储的是地址,在调用函数时,传递的也是地址,
在函数中通过地址改变对象上的内容,调用出也会一起改变,因为引用的都是一个地址
七,继承:
1, 什么是继承
a) 一个类使用extends关键字可以继承另一个类
b) 写法:class子类名extends 父类名 {}
c) 子类会继承到父类的属性和方法;
2, 什么时候使用继承;
a) 在定义一个类的时候,发现另一个类的功能这个类都需要,那么我们就可以再当前类名的后面使用extends关键字来继承另一个类
3, 多继承问题
Java中只支持单继承,类不能多继承(接口可以多继承),可以多重继承;因为一个类如果继承多个父类,如果父类中有相同的方法声明,子类就无法确定选用哪一个了
4, 继承的原理
子类之所以继承到父类的属性和方法,其实是在创建子类对象的时候也创建了一个父类对象;
访问子类的属性和方法时会先在子类中查找,找到就直接使用,找不到会使用父类的
5, super和this区别:
super是调用父类构造函数,this是调用当前类构造函数;
它们都是只能出现在构造函数的第一句,二者不能同时使用,只能选择其一;
构造函数的第一句要么是this,要么是super,如果没写,默认是super
练习:写出输出语句;------A E B D C F H G
class Test8 {
public static void main(String[] args) {
newB(); //AE BDC FHG
}
}
class A {
static {
System.out.println("A");
}
{
System.out.println("B");
}
A() {
this(123);
System.out.println("C");
}
A(int i) {
System.out.println("D");
}
}
class B extendsA {
static {
System.out.println("E");
}
{
System.out.println("F");
}
B() {
this(123);
System.out.println("G");
}
B(int i) {
System.out.println("H");
}
}
继承出现后,代码上也有一些特点:
1,变量。
当子父类中定义了相同的名称的成员变量,
子类要使用父类中的同名变量时,需要使用关键字super来区分。
一般不会出现这种情况,因为父类中有了,子类不需要定义。
而且父类定义时,一般变量都私有化。
2,函数。
子类可以直接访问父类中非私有的成员函数。
特殊情况:当子类中定义了与父类一模一样的方法时,会发生覆盖操作。大多指的是非静态方法。
最终会运行子类的方法,父类相当于被覆盖了。
函数的另一个特性:覆盖(重写,复写)。
什么时候用啊?
当父类的功能要被修改时,不建议修改源码。
只要通过一个类继承原有类,定义一个新的升级后的功能即可。
但是功能是相同的,只是实现方法改变。这是子类可以沿袭父类中的功能定义,
并重写功能内容。这就是覆盖。
覆盖注意事项:
1,子类覆盖父类时,必须权限要大于等于父类权限。
2,静态不能覆盖非静态。
3,构造函数。
构造函数可以本类进行对象初始化,也可以给子类对象进行初始化。
为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
7. 子类的实例化过程。
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。