6.1关键字:static
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。
编写一个类实现银行账户的概念,包含的属性有“帐号”、“密
码”、“存款余额”、“利率”、“最小余额”,定义封装这些
属性的方法。账号要自动生成。
编写主类,使用银行账户类,输入、输出3个储户的上述信息。
考虑:哪些属性可以设计成static属性。
package classTest5;
/**
* describe:
*
* @author suoliang
* @create 2021-06-13:27
*/
class Test{
public static void main(String[] args) {
Account account = new Account();
System.out.println(account);
Account account1 = new Account();
System.out.println(account1);
Account account2 = new Account();
System.out.println(account2);
}
}
public class Account {
private static int account=100;
private String password;
private int balance;
private static int rate;
private int min_bal;
public Account() {
++account;
}
@Override
public String toString() {
return "Account{" +
"password='" + password + '\'' + account + balance +
", balance=" + balance +
", min_bal=" + min_bal +
'}';
}
}
单例设计模式:
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。”套路”
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构 造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。
package classTest5;
/**
* describe:
*
* @author suoliang
* @create 2021-06-13:38
*/
public class Singleton {
//饿汉式
private String name;
private int age;
//1.私有化构造器
private Singleton(){}
//2.提供一个当前类的实例化
//4.此示例也必须静态化
private static Singleton singleton = new Singleton();
//3.提供公共的静态的方法,返回当前类的对象
public static Singleton show(){
return singleton;
}
}
package classTest5;
/**
* describe:
*
* @author suoliang
* @create 2021-06-13:38
*/
//懒汉式
class SingleTon2{
private String name;
//1.私有化构造器
private SingleTon2(){}
//2.先创建一个对象,但是不实例化
private static SingleTon2 single;
public static SingleTon2 show(){
if (single == null) {
single = new SingleTon2();
}
return single;
}
}
6.2理解main方法中的语法
class Something {
public static void main(String[] something_to_do) {
System.out.println("Do something ...");
} }
可以正常运行,只是一个形参
6.3类的成员之四.代码块
package classTest5;
由父及子,静态先行,然后父类代码块构造器---子类代码块构造器
/**
* describe:
*
* @author suoliang
* @create 2021-06-14:46
*/
class Root{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root(){
System.out.println("Root的无参数的构造器");
}
}
class Mid extends Root{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid(){
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:"
+ msg);
}
}
class Leaf extends Mid{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf(){
//通过super调用父类中有一个字符串参数的构造器
super("尚硅谷");
System.out.println("Leaf的构造器");
}
}
public class LeafTest{
public static void main(String[] args){
new Leaf();
//new Leaf();
}
}
6.4final关键字
6.5抽象类域抽象方法
问题1:为什么抽象类不可以使用final关键字声明?
final类不可以被继承,但是抽象类必须被继承才有用
问题2:一个抽象类中可以定义构造器吗?
可以,因为子类构造器需要调用父类中的构造器
问题3:是否可以这样理解:抽象类就是比普通类多定义了抽象方法,除了不能直接进行类的实例化操作之外,并没有任何的不同?
我认为可以
package classTest5;
/**
* describe:
*
* @author suoliang
* @create 2021-06-15:13
*/
public class test3 {
}
abstract class Employee{
private String name;
private int id;
private int salary;
public Employee(String name, int id, int salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
public Employee() {
}
public abstract void work();
}
class Manager extends Employee{
private int bonus;
@Override
public void work() {
System.out.println("经理");
}
}
class CommonEmployee extends Employee{
private int bonus;
@Override
public void work() {
System.out.println("普通员工");
}
}
package classTest5;
/**
* describe:
*
* @author suoliang
* @create 2021-06-15:18
*/
public class test {
public static void main(String[] args) {
Code1 code1 = new Code1();
code1.getTime();
Code2 code2 = new Code2();
code2.getTime();
}
}
/*
不同的方法有不同的时间
*/
abstract class SumClass{
/*
子类中通过code方法不同,实现使用的时间不同
*/
public abstract void code();
public void getTime(){
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println("所用时间为" + (end - start));
}
}
class Code1 extends SumClass{
@Override
public void code() {
for (int i = 0; i < 1000; i++){
System.out.println("哈哈哈");
}
}
}
class Code2 extends SumClass{
@Override
public void code() {
for (int i = 0; i < 10000; i++){
System.out.println("哈哈哈");
}
}
}
package com.atguigu.java;
//抽象类的应用:模板方法的设计模式
public class TemplateMethodTest {
public static void main(String[] args) {
BankTemplateMethod btm = new DrawMoney();
btm.process();
BankTemplateMethod btm2 = new ManageMoney();
btm2.process();
}
}
abstract class BankTemplateMethod {
// 具体方法
public void takeNumber() {
System.out.println("取号排队");
}
public abstract void transact(); // 办理具体的业务 //钩子方法
public void evaluate() {
System.out.println("反馈评分");
}
// 模板方法,把基本操作组合到一起,子类一般不能重写
public final void process() {
this.takeNumber();
this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
this.evaluate();
}
}
class DrawMoney extends BankTemplateMethod {
public void transact() {
System.out.println("我要取款!!!");
}
}
class ManageMoney extends BankTemplateMethod {
public void transact() {
System.out.println("我要理财!我这里有2000万美元!!");
}
}
//抽象方法其他类去做
package classTest5;
import java.util.FormatFlagsConversionMismatchException;
/**
* describe:
*
* @author suoliang
* @create 2021-06-15:25
*/
public class test5 {
public static void main(String[] args) {
MyDate myDate = new MyDate(2021,6,31);
SalariedEmployee employee = new SalariedEmployee("12", 12, myDate, 4000);
System.out.println(employee.earnings());
PayrollSyatem payrollSyatem = new PayrollSyatem();
Employee1[] employee1s = payrollSyatem.getEmployee1s();
for (int i = 0; i < employee1s.length; i++){
System.out.println(employee1s[i].earnings());
}
}
}
abstract class Employee1{
private String name;
private int number;
private MyDate brthday;
public abstract double earnings();
public Employee1() {
}
public Employee1(String name, int number, MyDate brthday) {
this.name = name;
this.number = number;
this.brthday = brthday;
}
public String getName() {
return name;
}
public int getNumber() {
return number;
}
public MyDate getBrthday() {
return brthday;
}
@Override
public String toString() {
return "Employee1{" +
"name='" + name + '\'' +
", number=" + number +
", brthday=" + brthday.toDateString() +
'}';
}
}
class MyDate{
private int year;
private int month;
private int day;
public MyDate() {
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public String toDateString(){
return year + "年" + month + "月" + day + "日";
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
}
class SalariedEmployee extends Employee1{
private double monthSalary = 3000;
public SalariedEmployee() {
}
public SalariedEmployee(String name, int number, MyDate brthday) {
super(name, number, brthday);
}
public SalariedEmployee(String name, int number, MyDate brthday, double monthSalary) {
super(name, number, brthday);
this.monthSalary = monthSalary;
}
@Override
public double earnings() {
if (this.getBrthday().getMonth() == 6){
monthSalary += 100;
}
return monthSalary;
}
}
class HourlyEmployee extends Employee1{
private int hour;
private int wage;
public HourlyEmployee(String name, int number, MyDate brthday, int hour, int wage) {
super(name, number, brthday);
this.hour = hour;
this.wage = wage;
}
public HourlyEmployee(String name, int number, MyDate brthday) {
super(name, number, brthday);
}
@Override
public double earnings() {
if (this.getBrthday().getMonth() == 6){
return hour * wage + 100;
}
return hour * wage;
}
}
class PayrollSyatem{
private Employee1[] employee1s = new Employee1[3];
public Employee1[] getEmployee1s() {
employee1s[0] = new HourlyEmployee("suo1",12,new MyDate(2021,5,12));
employee1s[1] = new SalariedEmployee("suo2",13,new MyDate(2021,6,12));
employee1s[2] = new SalariedEmployee("suo3",14,new MyDate(2021,7,12));
//employee1s[3] = new SalariedEmployee("suo",13,new MyDate(2021,6,12));
return employee1s;
}
}
6.6接口(interface)
接口(interface)是抽象方法和常量值定义的集合。
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
System.out.println(x);
//该:super.x访问父类中的x;A.x访问接口中的x
}
public static void main(String[] args) {
new C().pX();
} }
类和接口不会有冲突,自动调类的:类优先原则
6.7内部类