_ _ 8 static Singleton inheritance
Lead:
Think of writing
- The origin of static methods, and when to use. Static Precautions
- This section describes the main function parameters and pass
- Static variables, when to use? The difference between the member variables and local variables
- Static code block
- Configuration of code blocks and code blocks partial
- The step of loading the object. ★★★★★
- Paint practice. One of the Invincible interview questions (to paint himself bt). ★★★★★
- Singleton design pattern reflects two kinds, ★★★★★★
- Singleton applications, Superman
- Use of inheritance. Single and multiple inheritance of difference
1. The origin of the static method, and when to use. Static Precautions
/*
静态方法使用注意事项:
1,静态方法不能访问非静态的成员。
但是非静态可以访问静态成员的。
说明:静态的弊端在于访问出现局限性。好处是可以直接被类名调用。
2,静态方法中不允许出现this,super关键字。
为什么不行呢?
原理揭秘:
1,静态是随着类的加载就加载了。也是随着类的消失而消失了。
2,静态优先于对象存在,被对象共享。
3,因为静态先存在于内存中无法访问后来的对象的中的数据,所以静态无法访问非静态。
而且内部无法书写this。因为这时对象有可能不存在,this没有任何指向。
*/
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public void speak()
{
System.out.println("name="+this.name+",age="+this.age);
sleep();
}
//定义一个睡觉功能。
public static void sleep()
{
// System.out.println(name);
System.out.println("睡觉zzzZZZZ");
}
}
class PersonDemo
{
public static void main(String[] args)
{
// Person p = new Person("lisi",20);
// p.speak();
/*
创建对象就是为了产生实例,并进行数据的封装。
而调用功能时,确没有用到这些对象中封装的数据。
该对象的创建有意义吗?虽然可以编译并运行,但是在堆内存中空间较为浪费。
不建议创建对象。那该怎么调用呢?java中的解决方案就是 使用 static关键字,这是一个成员修饰符。
被静态static修饰的方法除了可以被对象调用外,还可以被类名调用。
静态看上去很美,是不是所有的方法都静态呢?不行!
那么什么时候需要将方法定义成静态的呢?
定义功能时,如果功能不需要访问类中定义的成员变量(非静态)时,该功能就需要静态修饰。
*/
// p.sleep();
Person.sleep();
}
}
2 describes how the main functions and pass parameters
/*
静态的主函数:
public static void main(String[] args)
public : 权限最大。
static :不需要对象。直接用给定的类名就可以访问该函数了。
void : 不需要返回值。
main : 函数名,该名称是固定的。
(String[] args) : 主函数的参数列表:字符串属性类型的参数。
args : arguments :参数。该名称就是一个变量名。
*/
class MainDemo
{
public static void main(String[] args)
{
System.out.println(args);//[Ljava.lang.String;@1afae45//根据这个结果,说明jvm传递了一个字符串类型的数组实体。
System.out.println(args.length);//0,得出结论 jvm传递的是 new String[0];
for (int i = 0; i<args.length ;i++ )
{
System.out.println(args[i]);
}
}
void show()
{
System.out.println("show run");
}
}
3. static variables, when to use? The difference between the member variables and local variables
/*
静态变量:
什么时候定义静态变量呢?
当该成员变量的值,每一个对象都一致时,就对该成员变量进行静态修饰。
静态变量和成员变量的区别:
1,所属范围不同。
静态变量所属于类,成员变量所属对象。
静态变量也称为:类变量;成员变量也称为实例变量。
2,调用不同。
静态变量可以被对象和类调用(一般都用类名调用)
成员变量只能被对象调用。
3,加载时期不同。
静态变量随着类的加载而加载。
成员变量随着对象的加载而加载。
4,内存存储区域不同。
静态变量存储在方法区中。
成员变量存储在堆内存中。
*/
class Circle
{
private double radius;//圆的半径。
private static double pi = 3.14;//每一个圆对象中都存储一份,有点浪费内存空间。实现对象的共享。加入静态关键字修饰。
Circle(double radius)
{
this.radius = radius;
}
//获取圆的面积。
double getArea()
{
return radius*radius*pi;
}
static void show()
{
System.out.println("circle show run.."+pi);
}
}
class CircleDemo
{
public static void main(String[] args)
{
Circle c = new Circle(3);
}
}
4. The static code block
/*
需求:类一加载,需要做一些动作。不一定需要对象。
学习目标:必须了解加载的顺序。
静态代码块:
特点:随着类的加载而执行,仅执行一次。
作用:给类进行初始化。
*/
class Demo
{
static int x = 9;//静态变量有两次初始化。 一次默认初始化,一次显示初始化。
{
System.out.println("i am gouzao code~");
}
Demo(){
System.out.println("i am demo()");
}
static //静态代码块。在静态变量显示初始化以后在执行。
{
System.out.println("类加载就执行的部..."+x);
}
static void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
public static void main(String[] args)
{
new Demo().show();
}
}
The configuration of the local code blocks and code block
/*
构造代码块:用于给所有的对象初始化。很少用并很少见。
*/
class Demo
{
int x = 4;//成员变量 1,默认初始化,2,显示初始化。
{// 构造代码块。只要创建对象就会被调用。给所有对象初始化,构造函数只给对应的对象针对性的初始化。
//这里面可以定义不同构造函数的共性代码。
System.out.println("code run..."+x);
// System.out.println("----->hahah");
}
Demo()
{
System.out.println("demo run");
}
Demo(int x)
{
System.out.println("demo run...."+x);
// System.out.println("----->hahah");
}
}
class ConstructorCodeDemo
{
public static void main(String[] args)
{
new Demo();
new Demo(5);
{//局部代码块,作用:就可以控制局部变量的生命周期。
int x = 5;
System.out.println(" 局部代码块..."+x);
}
System.out.println(" over...");
}
}
6. The loading step object. ★★★★★
/*
构造代码块:用于给所有的对象初始化。很少用并很少见。
*/
class Demo
{
int x = 4;//成员变量 1,默认初始化,2,显示初始化。
{// 构造代码块。只要创建对象就会被调用。给所有对象初始化,构造函数只给对应的对象针对性的初始化。
//这里面可以定义不同构造函数的共性代码。
System.out.println("code run..."+x);
// System.out.println("----->hahah");
}
Demo()
{
System.out.println("demo run");
}
Demo(int x)
{
System.out.println("demo run...."+x);
// System.out.println("----->hahah");
}
}
class ConstructorCodeDemo
{
public static void main(String[] args)
{
new Demo();
new Demo(5);
{//局部代码块,作用:就可以控制局部变量的生命周期。
int x = 5;
System.out.println(" 局部代码块..."+x);
}
System.out.println(" over...");
}
}
7. Paint practice. One of the Invincible interview questions (to be painted himself bt "/>. ★★★★★
class Demo
{
private static Demo d = new Demo();
Demo()
{
System.out.println("demo run");
}
}
class DemoDemo
{
public static void main(String[] args)
{
// try{
// new Demo();
// }catch(Throwable t)
// {
// System.out.println(t.toString());
// }
}
}
//画图。
class Test
{
static int x;
static int y = 1;
//static Test t = new Test();
static
{
System.out.println("x="+x+",y="+y);
}
Test()
{
x++;
}
}
class TestTest
{
public static void main(String[] args)
{
new Test();
}
}
/*
public class Demo2 {
public static int k = 0;
public static Demo2 t1 = new Demo2("t1");
public static Demo2 t2 = new Demo2("t2");
public static int i = print("i");
public static int j = print("j");
public static int n = 99;
{
print("constructor code");
}
static {
print("static code");
}
public static int print(String s) {
System.out.println("i="+i +" "+s+ " k=" + k + " n=" + n + " j=" + j);
++i;
++k;
++n;
return i;
}
public Demo2(String string) {
print(string);
}
public static void main(String[] args) {
Demo2 d=new Demo2("T");
}
}
*/
8. singleton design pattern reflects two kinds, ★★★★★★
/*
设计模式:解决某一类问题行之有效的解决办法(思想)。
单例(Singleton)设计模式:
学习设计模式必须先弄清楚它是解决什么问题的。
单例是解决什么问题的呢?
可以保证一个类的对象唯一性。
场景:比如多个程序都要使用一个配置文件中的数据,而且要实现数据共享和交换。
必须要将多个数据封装到一个对象中。而且多个程序操作的是同一个对象。
那也就是说必须保证这个配置文件对象的唯一性。
怎么能保证对象的唯一性呢?
1,一个类只要提供了构造函数,就可以产生多个对象。
完全无法保证唯一。
既然数量不可控,干脆,不让其他程序建立对象。
2,不让其他程序创建,对象何在?
干脆,自己在本类中创建一个对象,这样好处是什么,可控。
3,创建完成后,是不是要给其他程序提供访问的方式。
怎么实现这个步骤呢?
1,怎么就能不其他程序创建对象呢?
直接私有化构造函数,不让其他程序创建的对象初始化。
2,直接在本类中new一个本类对象。
3,定义一个功能,其他程序可以通过这个功能获取到本类的对象。
哦耶。
*/
//代码体现。
//饿汉式
class Single
{
//2,创建一个本类对象。
private static /*final*/ Single s = new Single();
//1,私有化构造函数。
private Single(){}
//3,定义一个方法返回这个对象。
public static Single getInstance()
{
return s;
}
}
//懒汉式
//单例的延迟加载方式。面试最多的是懒汉式。
class Single2
{
private static Single2 s2 = null;
private Single2(){}
public static Single2 getInstance()
{
if(s2==null)
s2 = new Single2();
return s2;
}
}
//练习:将两种方式的内存图画出来。
class SingleDemo
{
public static void main(String[] args)
{
//要想获取Single的对象。调用getInstance方法。既然无法通过对象调用,只能用类名调用,所以这个方法必须是static。
Single ss = Single.getInstance();
Single ss2 = Single.getInstance();
// Single ss = Single.s;//这种方式是可以实现,加入访问来获取就是为了对对象可控。
// Single ss2 = Single.s;
}
}
9. The single-mode embodiment of the application, Rider
//描述超人。
class SuperMan
{
private String name;
private static SuperMan man = new SuperMan("克拉克");
private SuperMan(String name)
{
this.name = name;
}
public static SuperMan getInstance()
{
return man;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public void fly()
{
System.out.println(this.name +"..fly");
}
}
class SingleTest
{
public static void main(String[] args)
{
//超人对象应该是唯一的。保证superMan的唯一性。可使用单例模式解决。
// SuperMan man = new SuperMan("克拉克");
SuperMan man1 = SuperMan.getInstance();
SuperMan man2 = SuperMan.getInstance();
man1.setName("英雄");
man2.fly();
}
}
10. The use of inheritance. Single and multiple inheritance of difference
/*
//描述学生。
class Student
{
//属性。
String name;
int age;
//行为。
void study()
{
System.out.println("good good study");
}
}
//描述工人。
class Worker
{
//属性。
String name;
int age;
//行为
void work()
{
System.out.println("hard work");
}
}
*/
/*
为了提高复用,只建立一份代码。
一个类只要和另一个类产生关系就可以了
关系:继承。
发现了获取到所需内容的同时也获取到不该具备的内容。
为什么?
发现原来这个两个类之间根本就不存在继承关系。
怎么解决呢?
找到学生和工人的共性类型。将需要提供复用的代码进行抽取。
定义到一个共性类型的类中。
Person name age。
怎么在代码体现中让学生和Person产生关系呢?
只要通过关键字 extends(继承) 就哦了。
*/
class Person
{
String name;
int age;
}
class Student extends Person//学生继承了Person 学生就是子类 Person就是父类(基类,超类)
{
void study()
{
System.out.println("good good study");
}
}
class Worker extends Person
{
void work()
{
System.out.println("hard work");
}
}
/*
面向对象 另一个特征:继承。
好处:提高了代码的复用性。让类与类产生了关系,给另一个特征 多态 提供了前提。
什么时候定义继承?
必须保证类与类之间有所属(is a)关系。 xxx是zzz中的一种。
苹果是水果中一种。狗是犬科中一种。
在Java中继承的体现:
Java允许单继承。不直接支持多继承,将多继承进行其他方式的体现。
单继承:一个子类只能有一个父类。
多继承:一个子类可以有多个父类。
看上起,多继承很厉害!为什么。
class Fu1
{
void show1()
{}
}
class Fu2
{
void show2()
{}
}
//多继承。
class Zi extends Fu1,Fu2
{
}
Zi z = new Zi();
z.show1();
z.show2();
//问题随之而来
万一多个父类具备了相同的功能呢?
class Fu1
{
void show()
{
sop("fu1 show run");
}
}
class Fu2
{
void show()
{
sop("fu2 show run");
}
}
//多继承。
class Zi extends Fu1,Fu2
{
}
Zi z = new Zi();
z.show();//调用就会产生不确定性。所以java保留的多继承的好处,改良它的弊端。用多实现来体现,即将学到。
--------------
java还支持多重继承。
class A
{}
class B extends A
{}
class C extends B
{}
形成继承体系。
学习继承体系时,应该参阅顶层的类中的内容。
了解这个体系的基本功能。
使用这个体系功能,需要创建最子类的对象。
看顶层,建底层。
*/
class ExtendsDemo
{
public static void main(String[] args)
{
Student stu = new Student();
stu.name = "xiaoqiang";
stu.age = 12;
stu.study();
}
}