day03面向对象

final修饰类/关键字
翻译为最终
可以修饰的内容:
1.类
2.方法
3.类中的成员变量

针对1:
在类的定义上使用final,表示最终类,太监类,不能继承,没有子类
定义类,功能非常完美了,不打算让子类进行扩展
最终类可以继承其他类,使用最终类创建对象,调用方法和final无关

针对2:
定义在方法的声明上,使用关键字final
最终方法
不能被子类重写
方法中的局部变量:final修饰局部变量,一次赋值终生不变,看成常量;final修饰引用类型变量,切记:final修饰引用变量,指的是引用类型保存的内存地址不能改。

针对3:
final修饰成员变量
类中的变量有默认值的
int–0
double–0.0
String扩展–null
boolean–false
char–‘|u0000’
final修饰符,固定的不是变量的默认值,一次赋值,直接=赋值,或者使用构造方法。
final修饰的成员变量,不能使用set方法赋值
构造方法:
作用,创建对象的,为对象中的数据初始化赋值
构造方法在创建对象的过程中
set方法:
set方法赋值,先把对象创建好
set方法运行的时机,是对象已经创建完毕
final关键字:编译成功后出现.class文件,class文件中是没有final的

public class Person {
    final String name;


    public Person() {
        this.name = "张三";
    }
}

public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        System.out.println(p.name);//打印出张三
    }
}

------------------------------------------------------

static关键字
01
static修饰符,静态
静态中的成员,变量还是方法
在内存方法区中存在,属于自己的类
和对象无关,是对象的共享数据
名词:
static修饰成员属于类,成员成为类成员
没有static修饰成员对象,对象数据

静态成员,多了一种调用方法:
类名.成员名(推荐使用类名调用)

静态成员是对象的共享数据

非静态成员属于对象,只能被对象调用

public class Student {
    String name;//学生姓名
    int age;//学生年龄
    static String classname="13134班";//所在班级
}

public class Test {
    public static void main(String[] args) {
        //类名直接调用静态成员
        System.out.println(Student.classname);//打印出13134班

        Student s1 = new Student();
        s1.name="张三";
        s1.age=18;
        s1.classname="黑马363";


        Student s2 = new Student();
        s2.name="李四";
        s2.age=20;
        s2.classname="白马363";//classname是共享的,相当于重新赋值

        System.out.println(s1.name+s1.age+s1.classname);
        System.out.println(s2.name+s2.age+s2.classname);


    }
}

02
静态使用的注意事项
静态方法中,不能直接使用非静态成员(非静态是可以引用静态的)
原因:
静态生命周期:优先于非静态的对象,存在于内存中(先人)
非静态生命周期:跟随对象,存在于内存中(后人)
静态成员方法中,不能写this,不能写super

public class Student {

    //对象变量,属于对象,非静态
    String name;

    //下面是非静态
    public void eat(){
        System.out.println(name+className);
    }

    //类变量,属于类,所有对象的共享,静态
    static String className="363";

    //创建静态方法
    public static void sleep(){
        //System.out.println(name+className);//报错了,因为不能直接使用非静态成员
        System.out.println(className);
    }
}

public class Test {
    public static void main(String[] args) {
        //非静态
        Student student = new Student();
        student.name="张三";
        student.eat();
        //静态
        Student.sleep();
    }
}

03
静态的调用问题
同一个类中,调用本类的方法,可以忽略类名不写(以前的时候)

静态可以修饰成员变量和成员方法
写程序的时候,什么时候定义静态成员变量,什么时候定义静态成员方法?
具体问题具体分析:当你分析事物,分析出事物之间的共享数据和特有数据,共享数据用静态修饰,特有数据也就是对象自己,用非静态修饰.
静态方法:当方法中没有使用过非静态成员的时候,方法就应该写成静态

public class Test {
    public static void main(String[] args) {
        //以前的
        System.out.println(getSum(1,1));

        //静态
        // 类名.方法名
        System.out.println(Test.getSum(1,2));
    }
    public static int getSum(int a,int b){
        return a+b;
    }

}

04
代码块:静态代码块;构造代码块;局部代码块.
静态代码块:
卸载类成员位置,static(),只运行一次,只要使用了该类成员,就运行且就一次.
数据库mysql中,java操作数据库中的数据,需要加载驱动包(类),一次即可,可以反复操作数据.
构造代码块:
写在类成员位置,无用
局部代码块:更无用

静态导入:导入包,必须到导入到类的成员位置,成员必须是静态的.

public class Student {
    //构造代码块
    {
        System.out.println("构造代码块");
    }


    //静态代码块
    static {
        System.out.println("静态代码块");
    }


    static int a=1;
}

public class Test {
    public static void main(String[] args) {
        System.out.println(Student.a);
    }
}

05
多态成员的编译运行:
静态成员变量:编译运行都是父类
静态成员方法:编译运行都是父类
非静态的方法:编译是父类,运行是子类

原因:对象的多态性,static不属于对象,内存早于对象

------------------------------------------------------

String方法的扩展

public class StringDemo {
    public static void main(String[] args) {
        method_5();
    }
    /**
     * String扩展[] split(字符串)切割字符串,返回数组
     */
    public static void method_7(){
        String[]str="ab  cd    ed  rf dd   ss".split(" +");
        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]);
        }
    }
    /**
     * int lastIndexOf(char ch)找字符,在字符串中最后一次出现的索引
     *
     */
    public static void method_6(){
        int num="how do you do".lastIndexOf('d');
        System.out.println(num);
    }

    /*
     *  byte[] getBytes()字符串变成数组,单个蹦出来的,因为遍历的原因
     */
    public static void method_5(){
        byte[]bytes="abcd".getBytes();
        for (int i = 0; i < bytes.length; i++) {
            System.out.println(bytes[i]);
        }
    }
    /**
     * boolean equalsIgnoreCase(String str)
     * 比较字符串,不考虑大小
     */
    public static void method_4(){
        boolean b="abc".equalsIgnoreCase("ABC");
        System.out.println(b);
    }

    /**
     *  int compareTo(String str) 字典顺序比较字符串
     *  a b c d  1234
     *
     *  str1.compareTo(str2); str1和str2比较
     *  调用者小于str2 结果是负数  < 0
     *  调用者大于str2 结果是正数  > 0
     *  调用者等于str2 结果是0
     */
    public static void method_3(){
        String str1="abc";
        String str2="aac";
        int num=str1.compareTo(str2);
        System.out.println(num);
    }

    /**
     * String(char[] bytes)
     * String(char[] bytes,int 开始索引,int 个数)
     */
    public static void method_2(){
        char[] ch= {'a','b','c','d'};
        String str = new String(ch);
        System.out.println(str);
    }

    /**
     * String(byte[] bytes)
     * String(byte[] bytes,int 开始索引,int 个数)
     * 97  a
     * 122 z
     *
     * 65 A
     * 90 Z
     *
     * 48 0
     * 57 9
     */
    public static void method_1(){
        byte[] bytes = {100,101,102,103,104};
        String str = new String(bytes,1,2);
        System.out.println(str);
    }
}

------------------------------------------------------

内部类
01
访问内部类(InnerClass)公式

类:分析事物的时候,具体的事物,定义为类
一个具体的事物的里面,包含了另一个具体的事物
举例:
车是一个事物,事物里面还有一个事物,引擎(发动机)
车是一个类,发动机也是一个,车是外部的类,发动机是车的内部的类

class A{
    class B{}
}

A是B的外部类,B是A的内部类
内部类可以直接使用外部类成员,包括私有
外部类使用内部成员,创建出内部类对象

成员内部类:类定义在一个类的成员位置
局部内部类:类定义在一个方法中

/**
 * Outer类,外部类
 * 成员内部类
 */
public class Outer {
    //成员位置,定义类,内部类
    class Inner{
        public void inner(){
            System.out.println("内部类方法");
        }
    }


   /* public void out(){
        //创建内部类的对象,调用方法
        Inner inner = new Inner();
        inner.inner();
    }*/
}

public class Test {
    public static void main(String[] args) {
//       Outer outer = new Outer();
//        outer.out();

        //访问内部类方法的公式
        //外部类名.内部类名   变量名=new  外部类对象.new内部类对象();
        Outer.Inner oi = new Outer().new Inner();
        oi.inner();
    }
}

02
访问特点

public class Outer {
    int a=3;//外部类的成员变量

    class Inner{
        int a=2;//内部类的成员变量

        public void inner(){
            int a=1;//方法内部变量
            System.out.println(a);
            System.out.println(this.a);//内部类的成员变量
            System.out.println(Outer.this.a);//外部类的成员变量
        }
    }
}

/*
* 内部类访问特点
* */
public class Test {
    public static void main(String[] args) {
        Outer.Inner oi=new Outer().new Inner();
        oi.inner();
    }
}

03
局部内部类

public class Outer {
    //定义方法
    public void out(){
        //方法体里面,定义类,局部的内部类
        class Inner{
            //定义局部内部类的方法,这里面不能用静态方法,因为非静态内部类中不能使用静态方法,以及非静态变量。
            public void inner(){
                System.out.println("局部内部类的方法");
            }
        }
        //创建内部类对象
        Inner inner = new Inner();
        inner.inner();
    }
}

/*
* 局部内部类,类定义在方法中
* */
public class Test {
    public static void main(String[] args) {
        //调用方法inner()
        Outer outer = new Outer();
        outer.out();
    }
}

04
匿名内部类
内部类,出现在方法中的内部类
匿名,没有名字
减少书写,减少的是继承父类或者接口
使用前提,必须有继承或者接口出现
伪代码
class MyInterfaceImpl implements MyInterface{
public void inter(){
System.out.println();
}
}
测试:创建实现类对象
MyInterface my = new MyInterfaceImpl();
my.inter();
以上程序的步骤:
1.定义接口实现类
2.实现类重写方法
3.创建实现类对象
匿名内部类:简化的是实现类实现接口
重写方法,创建对象

   格式:
     new 父类或者接口(){
         抽象方法的重写
      };

    专业上称为匿名内部类
   格式是在创建接口实现类的对象
public interface MyInterface {
    public abstract void inter();
}

public class Test {
    public static void main(String[] args) {
        /**
         *     new 父类或者接口(){
         *          抽象方法的重写
         *      };
         *      格式是在创建接口实现类的对象
         *      使用实现类对象直接调用方法
         */
        //new 接口
        new MyInterface(){
            //重写抽象方法
            public void inter(){
                System.out.println("实现类重写方法");
            }
        }.inter();
    }
}

05
重写多个

public interface MyInterface {
    public abstract void inter();
    public abstract void inter2();
}

/**
 *  使用匿名内部类的形式
 *  创建接口的实现类对象,并调用方法
 *  inter(),inter2()
 */
public class Test {
    public static void main(String[] args) {
        /*
        *    new 父类或者接口(){
        *        抽象方法的重写
        *    };
        *
        *    并调用方法
        *
        *    class xxx implements MyInterface{
        *         重写方法
        *         重写方法2
        *    }
        *     MyInterface my = new XXX();
         *      my.方法();
         *      my.方法2();
         *
         *
         * 匿名内部类,就是接口实现类对象
        * */


       MyInterface my= new MyInterface() {
            @Override
            public void inter() {
                System.out.println("实现类重写方法");
            }

            @Override
            public void inter2() {
                System.out.println("实现类重写方法222");
            }
        };
        my.inter();
        my.inter2();
    }
}

------------------------------------------------------

方法的参数

public abstract class Animal {
    public abstract void eat();
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

public interface MyInterface {
    void inter();
}

public class MyInterfaceImpl implements MyInterface {
    @Override
    public void inter() {
        System.out.println("实现类重写方法");
    }
}

public class Student {
    String name;
}

/**
 *  方法的参数:
 *
 *    public void xxx (参数列表){}
 *    参数列表可以是基本数据类型,也可以是引用数据类型
 */
public class Test {
    public static void main(String[] args) {

        //调用方法setStudent,传递对象
        // Student student = new Student();
        setStudent( new Student() );

        //调用方法setAnimal,传递他的子类对象
        setAnimal( new Cat() );

        //调用方法setMyInterface,传递接口实现类对象
        setMyInterface( new MyInterfaceImpl() );

    }
    /**
     * 创建方法:
     *   要求方法的参数是引用数据类型 MyInterface
     *   MyInterface是接口
     *   调用方法,传递接口实现类对象
     */
    public static void setMyInterface(MyInterface my){
        my.inter();
    }

    /**
     * 创建方法:
     *   要求方法的参数是引用数据类型Animal
     *   Animal是抽象类
     *   方法的参数是抽象类类型,调用者调用方法
     *   必须传递他的子类对象
     */
    public static void setAnimal(Animal animal){
        animal.eat();
    }


    /**
     * 创建方法:
     *  要求方法的参数是引用数据类型Student
     *  调用方法,请传递 Student的对象
     */
    public static void setStudent(Student student){
        //student操作成员变量
        student.name = "张三";
        System.out.println(student.name);
    }
}

------------------------------------------------------

方法的参数升级版
01

/**
 * 方法的返回值
 * 方法运行后的结果,结果的数据类型
 * 返回值可以是基本类型,也可以是引用数据类型
 */
public class Test {
    public static void main(String[] args) {
        //调用方法getStudent(),返回Student对象
        Student student = getStudent();
        System.out.println(student.name);


        //调用方法 getAnimal(),返回Animal类型
        Animal animal=getAnimal();
        animal.eat();

        //调用方法getMyInterface()接收返回值,接口类型
        MyInterface my = getMyInterface();
        my.inter();

    }

    /**
     * 创建方法:返回值是引用类型
     * 返回是MyInterface类型,接口
     * 方法中 return语句,必须返回接口实现类对象
     */
    public static MyInterface getMyInterface(){
        return new MyInterfaceImpl();
    }

    /**
     * 创建方法:返回值是引用类型
     * 返回的是Animal类型,是抽象类
     * 方法中 return语句,必须返回抽象类的子类对象
     */
    public static Animal getAnimal(){
        return new Cat();
    }


    /**
     *  创建方法: 返回值类型是引用类型
     *  Student,返回值类型写Student
     *  方法返回值,return 语句必须返回Student对象
     */
    public static Student getStudent(){
       // Student student = new Student();
        return new Student();
    }
}

02
返回值是抽象类

public abstract class Animal {
    /**
     * 抽象类,定义带有方法体的方法
     * 方便调用定义为静态修饰
     * 返回值,必须return 返回子类对象
     */
    public static Animal getAnimal(){
        return new Cat();
    }

    public abstract void eat();
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

/**
 * 方法的返回值是抽象类
 */
public class Test {
    public static void main(String[] args) {
        /**
         * 获取子类Cat类对象
         * 对象不是自己new的,而是通过方法来获取
         * 方法定义在了父类中
         *
         * 无子类现身,方便调用者
         *
         * 日历对象
         * new 日历对象()  语言,时区
         */
        Animal animal=Animal.getAnimal();
        animal.eat();
    }
}

------------------------------------------------------

权限修饰符

/**
 *  Java语言四大权限 JDK8以前
 *
 *                    public公共        protected受保护        default默认        private私有
 *   同一个类           Ok                   OK                    OK                 OK
 *   同一个包           OK                   OK                    OK                 NO
 *   不同包子类         OK                   OK                    NO                 NO
 *   不同包不是子类     OK                   NO                    NO                 NO
 *
 *   受保护权限 protected  给子类使用
 *   super.调用
 */

------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值