第四章 面向对象(下)

static关键字的使用

/*
* static关键字的使用
*1.static:静态的
*2.static可以用来修饰:属性、方法、代码块、内部类(不能修饰构造器)
*3.使用static来修饰属性:静态变量
*             3.1属性按是否使用static修饰分为:静态属性(静态变量)、非静态属性(实例属性)
*                      实例属性;创建类的多个对象,每个对象都独立的拥有一套类中的非静态属性,
*                                 当修改一个对象的非静态属性时,不影响其他对象的属性
*                      静态属性:创建了类的多个对象,所有对象公用一个静态变量。意味着通过某个对象修改静态变量时
*                                 会导致其他对象调用此静态变量时是修改过的
*             3.2 static修饰属性的其他说明:
*                      ①静态变量随着类的加载而加载
*                      ②静态变量的加载要早于对象的创建
*                      ③可以通过"类.静态变量"的方式调用静态变量
*                      ④由于类只加载一次,所以静态变量在内存中也只存在一份:存储在方法区的静态域中
*                      ⑤总结:
*                               静态变量           实例变量
*                      类       yes              no  (Chinese.name会报错)
*                      对象     yes              yes
*             3.3静态属性举例:System.out; Math.PI;
*
*4.使用static来修饰方法:静态方法
*        4.1随着类的加载而加载,可以通过"类.方法"的方式调用
*        4.2                    静态方法           非静态方法
*                      类       yes              no (Chinese.eat()会报错)
*                      对象     yes              yes
*
*        4.3在静态方法中,只能调用静态的方法或属性(生命周期一致)
*           非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
* 5.static注意点:
*        5.1在静态方法内,不能使用this、super关键字
*        5.2关于静态属性和静态方法的使用均从 生命周期 的角度去理解
* 6.
*             开发中如何确定一个属性是否要声明为static?
*             >>属性是可以被多个对象共享的,不会随着对象的不同而变化的
*             >>类中的常量也常声明为static的
*
*             开发中如何确定一个方法是否要声明为static?
*             >>操作静态属性的方通常设置为static的
*             >>工具类中的方法习惯上声明为static的:Math,Arrays,Collections
* */
public class StaticTest {
     public static void main(String[] args) {
          // 静态属性说明情况1:
          Chinese c1 = new Chinese();
          c1.nameString = "zoran";
          c1.age = 24;
          c1.nationString = "China";// 给c1的nationString属性赋值 China;没有给c2的nationString属性赋值
          Chinese c2 = new Chinese();
          c2.nameString = "ply";
          c2.age = 20;
          System.out.println(c2.nationString);// 打印c2的nationString,输出China
          // 静态属性说明情况2:
          Chinese c3 = new Chinese();
          c3.nameString = "zoran";
          c3.age = 24;
          c3.nationString = "China";// 先给c3的nationString赋值China
          Chinese c4 = new Chinese();
          c4.nameString = "ply";
          c4.age = 20;
          c4.nationString = "CHN";// 再给c2的nationString赋值CHN
          System.out.println(c3.nationString);// 打印c1的nationString:CHN
          System.out.println(Chinese.nationString);// 类.静态变量的方式调用 输出为:CHN
          System.out.println("***************************************");
          
          //静态方法
          Chinese.eat();//通过"类.方法"的方式调用静态方法,输出:Chinese can eat
     }
}
class Chinese {// 创建类
     String nameString;
     int age;
     static String nationString;
     public static void eat() {
//        info(); 报错 不能在静态方法中调用非静态方法
//        walk(); 不报错,可以在静态方法中调用静态方法
//        nameString="tom";报错,不能在静态方法中调用非静态属性
//        nationString="china";不报错,可以在静态方法中调用静态属性,其实是Chinese.naionStirng 省略了类名
          System.out.println("Chinese can eat");
     }
     public void info() {
          System.out.println("name : " + nameString  +  "age : " + age);
     }
     public static void walk() {
          
     }
}
//static关键字的应用举例
public class CircleTest {
     public static void main(String[] args) {
          Circle c1 = new Circle();
          Circle c2 = new Circle();
          Circle c3 = new Circle(3.5);
          System.out.println("c1的id: "+  c1.getId());//c1的id: 1001
          System.out.println("c2的id: "+  c2.getId());//c2的id: 1002
          System.out.println("c3的id: "+  c3.getId());//c3的id: 1003
          System.out.println("共创建了"+  Circle.getTotal()+ "个圆");//通过"类.属性"的方式调用静态属性
     }
}
class Circle{
     private double radius;
     private int id;
     private static int total=0;//记录创建的圆的个数
     private static int init = 1001 ;//多个对象共享id,每个圆对象都有自己的id
     
     public Circle() {
          total++;
          id = init++;//每创建一个圆对象,id自动+1
     }
     
     public Circle(double redius) {
          this();//调用构造器,相当于 total++;id=init++;
          this.radius=radius;
     }
     
     public double getRadius() {
          return radius;
     }
     
     public void setRadius(double radius) {
          this.radius = radius;
     }
     public int getId() {
          return id;
     }
     
     public static int getTotal() {
          return total;
     }
     private double findArea() {
          return 3.14*radius*radius;
     }
}
//举例2
/*
* 编写一个类实现银行账户的概念,包含的属性有:账号、密码、存款余额、利率、最小余额
* 定义封装这些属性的方法。账号要自动生成
* 编写主类,使用银行账户类输入输出3个储户的上述信息
* 考虑:那些属性可以设计成static属性
*
* */
public class Accout {
     //属性
     private static int inid=1000;
     private int id;//用于自动生成id
     private String  password = "123456";
     private double  balance;
     private static double rate;
     private static double MIN_BALANCE = 1.0;
     
     
     //构造器
     public Accout() {
          id=inid++;
     
     }
     public Accout(String password, double balance) {
          this();
          this.password = password;
          this.balance = balance;
     }
     
     
     //gs方法
     public String getPassword() {
          return password;
     }
     public void setPassword(String password) {
          this.password = password;
     }
     public static double getRate() {
          return rate;
     }
     public static void setRate(double rate) {
          Accout.rate = rate;
     }
     public static double getMIN_BALANCE() {
          return MIN_BALANCE;
     }
     public static void setMIN_BALANCE(double  mIN_BALANCE) {
          MIN_BALANCE = mIN_BALANCE;
     }
     public int getId() {
          return id;
     }
     public double getBalance() {
          return balance;
     }
     
     @Override
     public String toString() {
          return "Accout [id=" + id + ", password=" +  password + ", balance=" + balance + "]";
     }
          
     
}

public class AccoutTest {
     public static void main(String[] args) {
          Accout a1= new Accout();
          Accout a2= new Accout("123123",520.1314);
          
          Accout.setRate(0.0012);
          Accout.setMIN_BALANCE(100);
          
          System.out.println(a1);//默认调用对象的toString方法
          System.out.println(a2);
          
          System.out.println(a1.getRate());//0.012
          System.out.println(a2.getMIN_BALANCE());//100.0
          
     }
}

单例模式

/*
* 单例设计模式
* 1.就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例
* 2.如何实现
*        饿汉式
*        懒汉式
* 3.区分饿汉式和懒汉式
*        饿汉式:
*                 对象加载时间过长 但是 线程安全
*
*        懒汉式:
*                 延迟对象的创建 但是 线程不安全   --->多线程再改
*
* */
//单例模式饿汉式
public class SingletonTest {
     public static void main(String[] args) {
              Bank b1 =Bank.getInstanceBank();
              Bank b2 =Bank.getInstanceBank();
              
              System.out.println(b1==b2);//true
     }
}
class Bank{
     
     //1.私有化类的构造器
     private Bank() {
          
     }
     //2.内部创建类的静态对象
     private static Bank instanceBank = new Bank();
     //3.提供公共的静态的方法返回类的对象
     public static  Bank getInstanceBank() {
          return instanceBank;
     }
     
}
//单例模式的懒汉式
public class SingletonTest2 {
public static void main(String[] args) {
     Order o1 = Order.getInstance();
     Order o2 = Order.getInstance();
     
     System.out.println(o1==o2);//true
}
}
class Order{
     
     //1.私有化类的构造器
     private Order(){
          
     }
     //2.声明当前类的静态对象,不初始化
     private static Order  instance =null;
     
     //3.声明公共的静态方法返回当前类的对象
     public static Order getInstance() {
          if(  instance == null) {
          instance = new Order();
          }
          return instance;
     }
     
}

理解main方法的语法(了解即可)

/*
* main()的使用说明
* 1.main()方法作为程序的入口
* 2.是一个普通的static方法
* 3.main()可以作为与控制台交互的方式(之前使用Scanner)
* */
public class MainTest {
     public static void main(String[] args) {//入口
          Main.main(new String[100]);
          
     }
}
class Main{
     public static void main(String[] args) {
          for(int i = 0 ;i<args.length;i++) {
              args[i]="args_ "+i;
              System.out.println(args[i]);
          }
     }
}

类的成员之四:代码块

/*
* 类的成员之四:代码块(初始化块)
*
* 1.代码块的作用:
*             用来初始化类 或者 对象
* 2.代码块如果有修饰,只能用static
* 3.分类: 静态代码块 和 非静态代码块
*
* 4.静态代码块
*        >内部可以有输出语句
*        >静态代码块随着类的加载而执行且只执行一次(只会在类加载的时候执行一次)
*        >如果一个类中声明了多个静态代码块,按照声明的先后顺序执行
*         且静态代码块的执行优先于非静态代码块的执行(因为静态代码块随着类加载执行)
*        >静态代码块内部只能调用静态的属性与方法
*   作用:初始化类的信息
*        
* 5.非静态代码块
*        >内部可以有输出语句
*        >非静态代码块随着类的对象的创建而执行
*        >每创建一个对象,就会执行一次
*        >如果一个类中声明了多个非静态代码块,按照声明的先后顺序执行
*        >非静态代码块可以调用静态的属性方法或非静态的属性方法
*   作用:
*        可以在创建对象时,将对象的属性进行初始化
*
* 对属性可以赋值的位置:
*        ①默认初始化
*        ②显式初始化
*        ③构造器初始化
*        ④"对象.属性"、对象.set()方法"
*        ⑤在代码块中赋值
*
* 执行顺序:由父及子,静态先行
* */
public class BlockTest {
     public static void main(String[] args) {
          String descString = Person.descString;//hello  static block
          Person p1 = new Person();//hello  block
          Person p2 = new Person();//hello  block
          Person.info();//代码块不输出
          
          System.out.println(p1.age);//10
          System.out.println(Person.descString);// i am a  good person
     }
}
class Person {
     
     //属性
     String nameString;
     int age;
     static String descString="i am a person";
     
     //构造器
     public Person(String nameString, int age) {
          super();
          this.nameString = nameString;
          this.age = age;
     }
     public Person() {
          
     }
     
   //代码块
     //1.静态代码块
     static{
          System.out.println("hello static block");
          descString = " i am a good person";
     }
     static{
          System.out.println("hello static block-1");
     }
     
     //2.非静态代码块
     {
          System.out.println("hello  block");
          age =10;
          }
          
     //方法
     public void eat() {
          System.out.println("people can eat");
          
     }
     @Override
     public String toString() {
          return "Person [nameString=" + nameString + ",  age=" + age + "]";
     }
     public static void info() {
          System.out.println("i am  a  happy people");
     }
     
}
     

final关键字的使用

/*
* final:最终的
*   1.final可以用来修饰的结构:类、方法、变量
*   2.final 修饰类:此类不能被其他类继承
*                 比如:String System StringBuffer 等类
*   3.final 修饰方法:表名此方法不能被重写
*
*   4.final 修饰变量:此时的"变量"称为常量
*             4.1 final修饰属性:可以赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
*             4.2 final修饰局部变量
*                 尤其式final修饰形参时,表名此形参是一个常量,调用此方法给常量形参赋值后
*                 就只能在方法体内使用此形参,不能重新赋值
* static final 用来修饰一个属性:全局常量(尤其是接口)
* */                                                              看这些结论理解一下就行
public class FinalTest {
     final int width = 10;
     
     
     public void doWidth(){
//        width =20;  不能再次被赋值
     }
     
     
     
     
     
     public static void main(String[] args) {
     int num = 10;
     num = num+5;
     
}
}
final class FinalA{
      
}
// class B extends FinalA{} 类FinalA不能被继承
class AA{
      public final void show() {}
}
class BB extends AA{
//    public void show() {} 不能重写
}

抽象类与抽象方法

/*
* abstract关键字的使用
*        1.abstract:抽象的
*        2.abstract可以用来修饰的结构:类、方法
*
*        3.abstract修饰类:抽象类
*             >此类不能实例化
*             >抽象类中一定有构造器,便于子类对象实例化时调用(子类对象实例化的全过程)
*             >在开发中,都会提供抽象类的子类,让子类对象实例化完成相关操作
*
*        4.abstract修饰方法:抽象方法
*             >抽象方法只有方法的声明,没有方法体 public  abstract void method();
*             >包含抽象方法的类一定是一个抽象类,反之,抽象类中不一定有抽象方法(但是没必要)
*             >子类重写了父类中的所有抽象方法,才可以实例化
*             >若子类没有重写父类中的所有抽象方法,则子类也是一个抽象类
*
* */
public class AbstractTest {
     public static void main(String[] args) {
          //一旦Person类抽象了,就不能实例化
//        Person p1 = new Person();
//        p1.eat();
     }
}
abstract class  Person{
     String nameString;
     int age ;
     
     public Person() {
          super();
     }
     public Person(String nameString, int age) {
     
          this.nameString = nameString;
          this.age = age;
     }
     
     
     //抽象方法
     public abstract void  eat();
     public void walk() {
          System.out.println("people can walk");
     }
     
}
abstract class  Student extends Person{
          public Student(String nameString ,int age) {
              super(nameString ,age);
          }
//        public void eat() {
//            System.out.println("sutdent must eat  more");
//        }
}
/*
* abstract使用的注意点:
*        1.abstract不能修饰:属性、构造器等
*        2.abstract不能修饰私有方法(因为声明为private的方法不能重写)、静态方法(声明为static的方法不可成重写)、final的方法(不能重写)
*
* */
//练习题
/*
* 编写一个Employee类,声明为抽象类
* 包含以下三个属性:name id salary
* 提供必要的构造器和抽象方法:work()
*
* */
public abstract class Employee {
     private String name;
     private int id;
     private double salary;
     
     
     public Employee() {
          
     }
     public Employee(String name, int id, double salary)  {
     
          this.name = name;
          this.id = id;
          this.salary = salary;
     }
     
     
     public abstract void work();
     
}


public class Manager extends Employee{
     private double bonus;
     
     public Manager(String name, int id, double salary,  double bonus) {
          super(name, id, salary);
          this.bonus = bonus;
     }
     public Manager(double bonus) {
          super();
          this.bonus = bonus;
     }
     @Override
     public void work() {
          System.out.println("管理员工的人");
     }
     
}

public class CommonEmployee extends Employee {
     @Override
     public void work() {
          System.out.println("普通员工在一线工作");
     }
}

public class EmployeeTest {
     public static void main(String[] args) {
          //多态的使用
     Employee manager = new  Manager("zoran",1001,9000,5666);
     manager.work();
          //不使用多态
     CommonEmployee commonEmployee = new   CommonEmployee();
     commonEmployee.work();
          
     }
}
//应用
//抽象类的应用:模板方法的设计模式
public class TemplateTest {
     public static void main(String[] args) {
          Template template = new SubTemplate();
          template.spendTime();
     }
}
abstract class Template{
     //计算某段代码执行所需要的时间
     public void spendTime() {
          long start = System.currentTimeMillis();
          this.code();//不确定的部分、易变的部分
          
          long end = System.currentTimeMillis();
          System.out.println("执行代码花费的时间为:" +  (end - start));
                   
     }
     
     public abstract void code();
}
class SubTemplate extends Template{
     @Override
     public void code() {
          for(int i = 2;i<=1000;i++) {
              boolean isFlag = true;
              for(int j = 2;j<Math.sqrt(i);j++) {
                   if(i%j ==0) {
                        isFlag = false;
                        break;
                   }
              }
              if(isFlag) {
                   System.out.println(i);
              }
          }
          
     }
     
}

接口

/**
* 接口的使用
* 1.使用interface来定义一个接口
* 2.Java中,接口和类是两个并列的结构
* 3.如何定义接口:定义接口中的成员
*
*              3.1 JDK7以及以前:
*                  只能定义全局常量和抽象方法
*                  >全局常量:public static final的 (可以省略)
*                  >抽象方法:public abstract 的 可以省略)
*              3.2 JDK8:除此以外还可以定义静态方法、默认方法
*4.接口中不能定义构造器,即:接口不能实例化
*5.在java开发中,接口通过让 类去实现(implements)接口的方式来使用
*  如果实现类覆盖了接口中的所有抽象方法,则此实现类可以实例化
*  如果实现类没有覆盖接口中的所有方法,则此实现类仍为一个抽象类
*6.Java类可以实现多个接口:打破了单继承的局限性
*      格式: class AA extends BB implements CC,DD{}
*7.接口和接口之间可以继承,而且可以多继承
*8.接口的使用可以体现多态性
*9.接口可以看成一种规范
*
* 面试题:抽象类与接口有哪些异同?
*
@author shkstart
@create 2021-04-27-14:41
*/
public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MAX_SPEED);
        System.out.println(Flyable.MIN_SPEED);
        Plane p =new Plane();
        p.fly();
        p.stop();
        p.attack();
    }
}




interface Attackable{
    void attack();
}
interface  Flyable{
    //全局常量
    public static final int  MAX_SPEED = 7900;
    public static final int  MIN_SPEED = 1;
    //其中 pubilc static final 可是省略
    //int MAX_SPEED=7900;
    //int MIN_SPEED=1;


    //抽象方法
    public abstract void fly();
    public abstract void stop();
    //其中 public abstract 可是省略
    //void fly();
    //void stop();
}
class Plane implements  Flyable,Attackable {


    @Override
    public void fly() {
        System.out.println("plane can fly");
    }


    @Override
    public void stop() {
        System.out.println("plane can stop");
    }


    @Override
    public void attack() {
        System.out.println("warplane can attack");
    }
}
class Bullet extends Object implements Flyable,Attackable,CC{


    @Override
    public void attack() {


    }


    @Override
    public void fly() {


    }


    @Override
    public void stop() {


    }


    @Override
    public void method1() {


    }


    @Override
    public void method2() {


    }
}
//********************************************
interface AA{
    void method1();
}
interface BB{
    void method2();
}
interface CC extends AA,BB{


}
/**
* 接口的使用
*1.接口使用上满足多态性
*2.接口实际上定义了一种规范
* @author shkstart
* @create 2021-04-27-15:04
*/
public class USBTest {
    public static void main(String[] args) {
        Computer computer = new Computer();
        Flash flash  = new Flash();
        computer.transferDtata(flash);
    }
}


class Computer{
    public void transferDtata(USB usb){//USB usb = new Flash();
        System.out.println("具体的传输数据的细节");
        usb.start();
        usb.stop();
    }
}
interface USB{
    void start();
    void stop();
}
class Flash implements USB{


    @Override
    public void start() {
        System.out.println("start working");
    }


    @Override
    public void stop() {
        System.out.println("stop working");
    }
}
//应用
/*接口的应用:代理模式
*
* */
public class NetWorkTest {
     private static ProxyServer proxyServer;
     public static void main(String[] args) {
     Server server = new Server();
     ProxyServer   proxyServer = new ProxyServer(server  );
     proxyServer.browse();
     }
}
interface NetWork{
     public void browse();
}
//被代理类
class Server implements NetWork{
     @Override
     public void browse() {
     System.out.println("真实的服务器访问网络");
          
     }
     
}
//代理类
class ProxyServer implements NetWork{
     private NetWork work;
     
          public ProxyServer(NetWork work) {
          this.work = work;
     }
          
          
          public void check() {
              System.out.println("联网之前的检工作");
          }
     @Override
     public void browse() {
          check();
          work.browse();
     }
     
}

类的成员之五:内部类


```java
/*
* 类的内部成员之五:内部类
* 1.Java中允许将一个类A声明在另一个类B中,A为内部类,B为外部类
*
* 2.内部类的分类:成员内部类(静态与非静态)、局部内部类(方法内、代码块内、构造器内)
*
* 3.成员内部类:
*
*        一反面,作为外部类的成员:
*        >可以调用外部类的结构
*        >可以被static修饰
*        >可以被四种不同的权限修饰
*
*        另一方面,作为一个类:
*        >类内可以定义 属性 方法 构造器等
*        >可以用final修饰,表示此类不能被继承
*        >可以用abstract修饰,表示此类不能被实例化
*
*4.关注如下三个问题即可
*        4.1如何实例化成员内部类的对象
*        4.2如何在成员内部类中区分调用外部类的结构
*        4.3开发中 局部内部类的使用
*
* */
public class InnerClassTest {
     public static void main(String[] args) {
          //创建Dog的实例(静态的成员内部类)
          Person.Dog dog = new Person.Dog();
          dog.show();
          
          //创建Bird实例(非静态的成员内部类)
          Person p1 = new Person();
          Person.Bird bird = p1.new Bird();
          bird.sing();
          
          bird.display("黄鹂");
          
     }
}
class Person{
     
     String nameString;
     int age;
     public void eat() {
          System.out.println("people can eat");
     }
     //静态成员内部类
static  class Dog{
          String nameString;
          int age;
          public void show() {
              System.out.println("i am a dog");
              
          }
          
     }
     //非静态成员内部类
      class Bird{
          String nameString ;
          public void sing() {
              System.out.println(" i am a bird");
              Person.this.eat();//调用外部类的方法
          }
          
      public void display(String nameString) {
           System.out.println(nameString);//方法的形参
           System.out.println(this.nameString);//内部类的属性
           System.out.println(Person.this.nameString);//外部类的属性
      }
     }
     
     public void method() {
          //局部内部类
          class AA{
              
          }
          
          {
          //局部内部类
              class BB{
                   
              }
          }
          
     }
     
     public Person() {
          //局部内部类
          class CC{
              
          }
     }
     
}

```java
/* 4.3开发中 局部内部类的使用
*
*
*/
public class InnerClassTest1 {
     //开发中很少见
     public void method() {
          //局部内部类
          class AA{
              
          }
     }
     
     //返回一个实现了Comparable接口的类的对象
     public Comparable getComparable() {
          //创建一个实现了Comparable接口的类:局部内部类
          class MyComparable implements Comparable{
              @Override
              public int compareTo(Object o) {
                   // TODO Auto-generated method stub
                   return 0;
              }
              
          }
          
          return new MyComparable();
          
          //方式二
//        return new Comparable() {
//
//            @Override
//            public int compareTo(Object o) {
//                 // TODO Auto-generated method stub
//                 return 0;
//            }
//            
//        };
//        
          
          
          
          
     }
     
     
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值