zoukankan      html  css  js  c++  java
  • 05 面向对象:构造方法&static&继承&方法 &final

    构造方法及其重载:

    /*
    构造方法格式特点
        * a:方法名与类名相同(大小也要与类名一致)
        * b:没有返回值类型,连void都没有
        * c:没有具体的返回值return;
        * 构造方法的重载
        * 重载:方法名相同,与返回值类型无关(构造方法没有返回值),只看参数列表
    构造方法注意事项
        * a:如果没有给出构造方法,系统将自动提供一个无参构造方法。
        * b:如果给出了构造方法,系统将不再提供默认的无参构造方法。
            * 注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出
    */
    class Demo_Constructor {
        public static void main(String[] args)
        {
            Person p = new Person("lee",18);
            p.show();
        }
    }
    class Person{
        private String name;
        private int age;
    
        public Person(){} // 构造方法
    
        public Person(String uname,int uage){ // 构造方法的重载
            this.name = uname;
            this.age = uage;
        }
    
        public void show(){
            System.out.println("name:"+name+",age:"+age);
        }
    }

    成员变量的赋值:

    /*
    成员变量的赋值
    */
    class Demo_Person1 {
        public static void main(String[] args)
        {
            Person p1 = new Person("李四",18);
            p1 = new Person("李四",19); // //运行结果貌似是改名了,其实是将原对象变成垃
    
    圾
            System.out.println("name:"+p1.getName()+"age:"+p1.getAge());
            Person p2 = new Person(); // //空参构造创建对象
    
            p2.setName("王五");
            p2.setAge(19);
            System.out.println("name:"+p2.getName()+"age:"+p2.getAge());
        }
    }
    class Person{
        private String name;
        private int age;
        public Person(){}
    
        public Person(String name,int age){
            this.name = name;
            this.age = age;
        }
    
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
    
        public void setAge(int age){
            this.age = age;
        }
        public int getAge(){
            return age;
        }
        
    }


    创建一个对象的步骤
    * 例:
        * Student s = new Student();
        * 1,Student.class加载进内存
        * 2,声明一个Student类型引用s
        * 3,在堆内存创建对象,
        * 4,给对象中属性默认初始化值
        * 5,属性进行显示初始化
        * 6,构造方法进栈,对对象中的属性赋值,构造方法弹栈
        * 7,将对象的地址值赋值给s
    static关键字:

    /*
    static关键字的特点
        * a:随着类的加载而加载
        * b:优先于对象存在
        * c:被类的所有对象共享
        * d:可以通过类名调用
            * 其实它本身也可以通过对象名调用。
            * 推荐使用类名调用。
            * 静态修饰的内容一般我们称其为:与类相关的,类成员
    如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
    */
    class Demo_Person2 {
        public static void main(String[] args)
        {
            Person p1 = new Person();
            p1.setName("李四");
            p1.setCountry("cn");
            System.out.println(p1.getName()+p1.getCountry()); // 李四cn
    
            Person p2 = new Person();
            p2.setName("王五");
            System.out.println(p2.getName()+p2.getCountry()); // 王五cn
        }
    }
    class Person{
        static String country;
        String name;
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
    
        public void setCountry(String country){
            this.country = country;
        }
        public String getCountry(){
            return country;
        }
    }

    static的注意事项
        * a:在静态方法中是没有this关键字的
            * 如何理解呢?
                * 静态是随着类的加载而加载,this是随着对象的创建而存在。
                * 静态比对象先存在。
        * b:静态方法只能访问静态的成员变量和静态的成员方法
            * 静态方法:
                * 成员变量:只能访问静态变量
                * 成员方法:只能访问静态成员方法
            * 非静态方法:
                * 成员变量:可以是静态的,也可以是非静态的
                * 成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
            * 简单记:
                * 静态只能访问静态。

    class Demo_Person3 {
        public static void main(String[] args)
        {
            Demo d = new Demo();
            d.showDemo1();
    
            Demo.showDemo2();
        }
    }
    
    class Demo{
        static String country = "cn";
        String name = "李四";
        
        public void showDemo1(){
            System.out.println(country);
            System.out.println(name);
            // 相当于
            System.out.println(this.name); // this可以省略
        }
        public static void showDemo2(){
            System.out.println(country);
        //    System.out.println(name);// 错误: 无法从静态上下文中引用非静态 变量 name
        //    System.out.println(this.name); //
        }
    }

    静态变量和成员变量的区别:
    * 静态变量也叫类变量  成员变量也叫对象变量
    * A:所属不同
        * 静态变量属于类,所以也称为为类变量
        * 成员变量属于对象,所以也称为实例变量(对象变量)
    * B:内存中位置不同
        * 静态变量存储于方法区的静态区
        * 成员变量存储于堆内存
    * C:内存出现时间不同
        * 静态变量随着类的加载而加载,随着类的消失而消失
        * 成员变量随着对象的创建而存在,随着对象的消失而消失
    * D:调用不同
        * 静态变量可以通过类名调用,也可以通过对象调用
        * 成员变量只能通过对 象名调用

    main方法的格式解释:

    class Demo3_Main {
        public static void main(String[] args) {            
            /*
            public : 被jvm调用,所以权限要足够大
            static : 被jvm调用,不需要创建对象,直接类名.调用即可
            void   : 被jvm调用,不需要有任何的返回值
            main   : 只有这样写才能被jvm识别,main不是关键字
            String[] args : 以前是用来接收键盘录入的
            */
    
            System.out.println(args.length);
            for (int i = 0;i < args.length ;i++ ) {
                System.out.println(args[i]);
            }
        }
    }


    说明书的制作过程:
    对工具类加入文档注释
    通过javadoc命令生成说明书
        * @author(提取作者内容)
        * @version(提取版本内容)
        * javadoc -d 指定的文件目录 -author -version ArrayTool.java
        * @param 参数名称//形式参数的变量名称
        * @return 函数运行完返回的数据
    // javadoc -d api -version -author ArrayTool.java

    /**
    这是一个数组工具类,里面封装了查找数组最大值,打印数组,数组反转的方法
    @author fly
    @version v1.0
    */
    public class ArrayTool {
        //如果一个类中所有的方法都是静态的,需要再多做一步,私有构造方法,目的是不让其他类创建
    
    本类对象
        //直接用类名.调用即可
        /**
        私有构造方法
        */
        private ArrayTool(){} //设计模式:单例模式
    
        //1,获取最大值
    
        /**
        这是获取数组中最大值的方法
        @param arr 接收一个int类型数组
        @return 返回数组中最大值
        */
        public static int getMax(int[] arr) {
            int max = arr[0];                        //记录第一
    
    个元素
            for (int i = 1;i < arr.length ;i++ ) {    //从第二个元素开始遍历
                if (max < arr[i]) {                    //max与数组
    
    中其他的元素比较
                    max = arr[i];                    //记录住较
    
    大的
                }
            }
    
            return max;                                //
    
    将最大值返回
        }
        //2,数组的遍历
        /**
        这是遍历数组的方法
        @param arr 接收一个int类型数组
        */
        public static void print(int[] arr) {
            for (int i = 0;i < arr.length ;i++ ) {    //遍历数组
                System.out.print(arr[i] + " ");
            }
        }
        //3,数组的反转
        /**
        这是数组反转的方法
        @param arr 接收一个int类型数组
        */
        public static void revArray(int[] arr) {
            for (int i = 0;i < arr.length / 2 ;i++ ) {    //循环次数是元素个数的一半
                /*
                arr[0]与arr[arr.length-1-0]    交换
                arr[1]与arr[arr.length-1-1]    交换
                arr[2]与arr[arr.length-1-2] 交换
                */
                int temp = arr[i];
                arr[i] = arr[arr.length-1-i];
                arr[arr.length-1-i] = temp;
            }
        }
    }
    View Code


    random:

    import java.util.Scanner;
    /*
    class Demo_Math {
        public static void main(String[] args)
        {
        //    double d = Math.random(); // 返回带正号的 double 值,该值大于等于 0.0 且小
    
    于 1.0。返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。
        //    System.out.println(d);
        }
    }
    */
    class Demo_Math {
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            System.out.println("输入一个1~100之间的整数");
            int g = (int)(Math.random()*100)+1;
            while (true)
            {
                int re = sc.nextInt();
                if (re > g)
                {
                    System.out.println("大了");
                }else if (re < g)
                {
                    System.out.println("小了");
                }else{
                    System.out.println("猜中了");
                    break;
                }
    
            }
    
        }
    }

    代码块:

    /*
    局部代码块
        * 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
    构造代码块 (初始化块)
        * 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并
    
    且在构造方法前执行
    静态代码块
        * 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且
    
    只执行一次。优先于主方法执行。
        * 一般用于加载驱动
    
    */
    class Demo1_Code {
        public static void main(String[] args)
        {
            {
                //局部代码块
                int x = 10;
            }
        //    System.out.println(x); // 错误: 找不到符号 x
            new Stu();
            new Stu();
        }
        
        static {
            System.out.println("主方法类中的静态代码块");
        }
    }
    class Stu{
        public Stu(){
            System.out.println("构造方法");
        }
        {
            //构造代码块
            study();
        }
        public void study(){
            System.out.println("xx-----");
        }
        static {
            System.out.println("Stu中的静态代码块");
        }
    }
    /*
    
    主方法类中的静态代码块
    Stu中的静态代码块
    xx-----
    构造方法
    xx-----
    构造方法
    */


    继承:
       让类与类之间产生关系,子父类关系

    继承的好处和弊端:
    * A:继承的好处
        * a:提高了代码的复用性
        * b:提高了代码的维护性
        * c:让类与类之间产生了关系,是多态的前提
    * B:继承的弊端
        * 类的耦合性增强了。
        
        * 开发的原则:高内聚,低耦合。
        * 耦合:类与类的关系
        * 内聚:就是自己完成某件事情的能力

    Java中类的继承特点:
    * A:Java中类的继承特点
        * a:Java只支持单继承,不支持多继承。(一个儿子只能有一个爹)
            * 有些语言是支持多继承,格式:extends 类1,类2,...
        * b:Java支持多层继承(继承体系)
    *
        * 如果想用这个体系的所有功能用最底层的类创建对象
        * 如果想看这个体系的共性功能,看最顶层的类

    子类只能继承父类所有非私有的成员(成员方法和成员变量)
    子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。

    this和super都代表什么
        this:代表当前对象的引用,谁来调用我,我就代表谁
        super:代表当前对象父类的引用
    this和super的使用区别
        a:调用成员变量
            this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
            super.成员变量 调用父类的成员变量
        b:调用构造方法
            this(...)    调用本类的构造方法
            super(...)    调用父类的构造方法
        c:调用成员方法
            this.成员方法 调用本类的成员方法,也可以调用父类的方法
            super.成员方法 调用父类的成员方法
            
    子类中所有的构造方法默认都会访问父类中空参数的构造方法
    因为子类会继承父类中的数据,可能还会使用父类的数据。
    所以,子类初始化之前,一定要先完成父类数据的初始化。

    super(…)或者this(….)必须出现在构造方法的第一条语句上
    */

    class Demo_extends {
        public static void main(String[] args)
        {
        //    new Son().A();
            new Son();
        }
    }
    class Father
    {
        int a = 10;
        int b = 30;
        private int c = 40;
        public Father(){  // Object类最顶层的父类
            System.out.println("Father的构造方法");
        }
        public Father(int a,int b){  
            this.a = a;
            this.b = b;
            System.out.println("a:"+a+"b:"+b); // a:10b:10
        }
    }
    class Son extends Father
    {
        int a = 20;
        public Son(){
        //    super(); // 系统默认会加上,用来访问父类的空参构造
            this(10,10); // 调用自类的有参构造
        }
        public Son(int a,int b){
            super(a,b); // 调用父类的有参构造
        }
        public void A(){
            System.out.println(this.a); //20
            System.out.println(super.a); //10
            System.out.println(this.b); //30
        //    System.out.println(super.c); //错误: c 在 Father 中是 private 访问控制
        }
        
    }
    View Code

    继承含有代码块的执行顺序:

    class Demo_extends2 {
        public static void main(String[] args)
        {
            new B();
        }
    }
    class A
    {
        static{
            System.out.println("静态代码块A");
        }
        {
            System.out.println("构造代码块A");
        }
        public A(){
            System.out.println("构造方法A");
        }
    }
    class B extends A
    {
        static{
            System.out.println("静态代码块B");
        }
        {
            System.out.println("构造代码块B");
        }
        public B(){
            System.out.println("构造方法B");
        }
    }
    /*
    
    静态代码块A
    静态代码块B
    构造代码块A
    构造方法A
    构造代码块B
    构造方法B
    */

    方法重写概述及其应用:
    * A:什么是方法重写
        * 重写:子父类出现了一模一样的方法(注意:返回值类型可以是子父类)
    * B:方法重写的应用:
        * 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样

    ,即沿袭了父类的功能,又定义了子类特有的内容。

    方法重写的注意事项:
    * A:方法重写注意事项
        * a:父类中私有方法不能被重写
            * 因为父类私有方法子类根本就无法继承
        * b:子类重写父类方法时,访问权限不能更低
            * 最好就一致
        * c:父类静态方法,子类也必须通过静态方法进行重写
            * 其实这个算不上方法重写,但是现象确实如此,(静态只能覆盖静态)
            
        * 子类重写父类方法的时候,最好声明一模一样。


    方法重写与重载:
        * Override和Overload(重载)的区别?Overload能改变返回值类型吗?
        * overload可以改变返回值类型,只看参数列表
        * 方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一

    致(或者是子父类)的
        
        * 方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

        * 子类对象调用方法的时候:
            * 先找子类本身,再找父类。


    final修饰变量的初始化时机:

    class Demo3_Final {
        public static void main(String[] args) {
            Demo d = new Demo();
            d.print();
        }
    }
    /*
    * A:final修饰变量的初始化时机
        * 显示初始化
        * 在对象构造完毕前即可
    */
    
    class Demo {
        final int num;    //没有后面的num = 10;,就错误了,成员变量的默认初始化值是无效值
        
        public Demo() {
            num = 10;  //  在对象构造完毕前即可
        }
        public void print() {
            System.out.println(num);
        }
    }
  • 相关阅读:
    IDEA搭建《算法》第四版的开发环境
    tomcat源码环境搭建
    cap定理
    idea jdk 源码搭建
    2020-04-07 学习记录
    idea 格式化代码
    Ajax工作原理
    prototype封装继承
    作用域
    原型链的原理
  • 原文地址:https://www.cnblogs.com/fly-book/p/9841615.html
Copyright © 2011-2022 走看看