• Java基础(二)面向对象(上)


    面向对象基础知识

    面向对象是相对面向过程而言的 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象 面向对象是基于面向过程的

    面向对象的特征:

    • 封装
    • 继承
    • 多态

    java中用类Class来描述事物: 属性:对应类中的成员变量 行为:对应类中的成员函数

    成员变量 成员变量定义在类中,在整个类中都可以被访问 成员变量随着对象的建立而建立,存在于对象所在的堆内存中 成员变量有默认初始化值

    局部变量 局部变量之定义在局部范围内,如函数内 局部变量存在栈内存中 作用的范围结束,变量空间会自动释放 局部变量没有默认初始化值

    匿名对象 匿名对象是对象的简化形式 匿名对象有两种使用情况: 当对象方法仅进行一次调用时 匿名对象可以作为实际参数进行传递

    heap-stack

    java -x 输出java的非标准选项 java -Xss<size> xxx 设置stack大小 如:java -Xss521k

    java -Xmx 设置堆最大值 java -Xms 设置堆初始值

    java中对象和数组都位于堆内存中,局部变量函数参数等都位于栈内存中

    封装

    封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式

    封装原则: 将不需要对外提供的内容都隐藏起来 把属性都隐藏起来,提供公共方法对其访问

    代码例子:

    package study_java.ex01;
    
    public class ClassDemo1 {
        public static void main(String[] args){
            Man man = new Man();
            // 不能直接通过man访问到money,只能通过getMoney方法
            System.out.println(man.getMoney());
            man.addMoney(100);
            System.out.println(man.getMoney());
            // 对于public的变量我们可以直接通过man访问
            System.out.println(man.age);
        }
    
    }
    
    class Man{
        private int money = 100;
        public int age = 23;
    
        // 通过封装的方式获取money
        public int getMoney(){
            return money;
        }
        // 通过封装的方式修改money
        public void addMoney(int num){
            money += num;
        }
    }

    private关键字

    是一个权限修饰符 用于修饰成员变量和成员函数 被私有化的成员只在本类中有效

    常用于: 将成员变量私有化,对外提供对应的set,get方法对其进行访问,提高对数据访问的安全性

    构造函数

    函数名与类名相同 不用定义返回值类型 没有具体的返回值

    作用:给对象进行初始化

    package study_java.ex01;
    
    public class ConstructDemo1 {
    
        public static void main(String[] args){
            Dog d = new Dog("aa");
            d.watch();
        }
    }
    
    class Dog{
        private String name;
        private String color;
    
        // 构造函数
        public Dog(String n){
            name = n;
            System.out.println("new Dog()");
        }
    
        public void watch(){
            System.out.println("旺旺");
            System.out.println(name);
        }
    
    }

    构造代码块也是类成员,是为构造函数添加共有的一些内容 并且构造函数先于构造函数执行

    对象的创建过程: 当new一个对象的时候

    • 在内个存中分配内存空间
    • 对成员变量赋默认值
    • 执行构造代码块或赋值语句,执行顺序从上到下执行
    • 构造函数

    静态代码块

    使用static修饰的代码构造块,在类加载的时候调用一次,以后不再调用。 通常放置对静态成员的初始化过程

    static成员,跟对象无关,访问的方式是通过Class.XXX()

    this关键字

    this:代表其所在函数所属对象的引用,即this代表类对象的引用

    static 关键字

    用于修饰成员(成员变量和成员函数)

    被修饰后的成员具备以下特点: 随着类的加载而加载 优先于对象存在 被所有的对象所共享 可以直接被类名调用

    使用注意: 静态方法只能访问静态成员 静态方法不能写this,super关键字 主函数是静态的

    代码例子如下:

    package study_java.ex01;
    
    public class StaticDemo1 {
        public static void main(String[] args){
            System.out.println(Benz.brand1);
    
            Benz b1 = new Benz();
            System.out.println(b1.getBrand());
    
            // 直接访问静态方法
            System.out.println(Benz.getBrand1());
        }
    }
    
    class Benz{
        // 静态成员
        private static String brand = "BENZ";
    
        public static  String brand1 = "BENZ1";
    
        private String color;
    
        public void setColor(String color){
            this.color = color;
        }
    
        public String getBrand(){
            return brand;
        }
    
        public static String getBrand1(){
            return brand;
        }
    }

    this(): 调用其他构造函数的方式,而且必须作为第一条语句

    继承

    多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

    多个类可以称为子类,单独这个类称为父类 子类可以直接访问父类中国非私有的属性和方法 通过extends关键字让类与类之间产生继承 java中只支持单冲继承 + 多层继承

    简单的例子:

    package study_java.ex01;
    
    public class ExtendsDemo1 {
    
        public static void main(String[] args){
            JingBa jingba = new JingBa();
            jingba.name = "大黄";
            jingba.watch();
            jingba.owner="zz";
        }
    
    
    }
    
    
    class Animal{
        public String name;
        public int weight;
        public void move(){
            System.out.println("move.....");
        }
    }
    
    class Dog extends Animal{
        public void watch(){
            System.out.println("有人来了");
        }
    }
    
    class JingBa extends Dog{
        public String owner;
    }

    super关键字

    调用的是父类的构造函数,必须是第一条语句 通过下面例子理解:

    package study_java.ex01;
    
    public class ExtendsDemo2 {
    
        public static void main(String[] args){
            // 创建对象
            BMWSportCar mychar = new BMWSportCar();
            mychar.color = "red";
            mychar.velocity = 200;
            mychar.price = 20000;
            mychar.run();
    
        }
    }
    
    class Car{
        public String color;
        public void run(){
            System.out.println("running.....");
        }
    
        public Car(String color){
            this.color = color;
            System.out.println("new car("+color+")");
        }
    }
    
    class SportCar extends Car{
        public int velocity;
        public SportCar(int velocity){
            super("yellow");
            this.velocity = velocity;
            System.out.println("new SportCar("+velocity +")");
        }
    }
    
    class BMWSportCar extends SportCar{
        public int price;
    
        public BMWSportCar(){
            super(200);
            System.out.println("new BMWSportCar");
        }
    }

    如果被继承的父类的属性是私有的,如果想要访问或者更改,可以通过定义公有的方法来实现,代码例子如下:

    package study_java.ex01;
    
    public class ExtendsDemo2 {
    
        public static void main(String[] args){
            // 创建对象
            BMWSportCar mychar = new BMWSportCar();
            mychar.setColor("red");
            mychar.velocity = 200;
            mychar.price = 20000;
            mychar.run();
            System.out.println(mychar.getColor());
    
        }
    }
    
    class Car{
        //私有属性
        private String color;
        public void run(){
            System.out.println("running.....");
        }
    
        public Car(){
    
            System.out.println("new car()");
        }
        // 公有方法
        public String getColor(){
            return color;
        }
        public void setColor(String color){
            this.color = color;
        }
    }
    
    class SportCar extends Car{
        public int velocity;
        public SportCar(){
            System.out.println("new SportCar()");
        }
    }
    
    class BMWSportCar extends SportCar{
        public int price;
    
        public BMWSportCar(){
            System.out.println("new BMWSportCar");
        }
    }

    super和this的用法有点相似

    • this代表本类对象的引用
    • super代表父类的内存空间的标识
    • 子类要调用父类构造函数时,可以使用super()语句
    • 当子类和父类出现同名成员时,可以用super进行区分

    super()和this()

    调用父类的构造函数,必须是第一条语句

    package study_java.ex01;
    
    public class ExtendsDemo2 {
    
        public static void main(String[] args){
            // 创建对象
            BMWSportCar mychar = new BMWSportCar();
            mychar.setColor("red");
            mychar.velocity = 200;
            mychar.price = 20000;
            mychar.run();
            System.out.println(mychar.getColor());
    
        }
    }
    
    class Car{
        //私有属性
        private String color;
        public void run(){
            System.out.println("running.....");
        }
    
        public Car(){
    
            System.out.println("new car()");
        }
        // 公有方法
        public String getColor(){
            return color;
        }
        public void setColor(String color){
            this.color = color;
        }
    }
    
    class SportCar extends Car{
        public int velocity;
        public SportCar(){
            System.out.println("new SportCar()");
        }
        public void setColorPro(String color){
            // this.color = color;  //这里和下面的的super是一样的
            super.setColor(color);
        }
    
        public void setColor(String color){
            super.setColor(color);
        }
    
    }
    
    class BMWSportCar extends SportCar{
        public int price;
    
        public BMWSportCar(){
            System.out.println("new BMWSportCar");
        }
    }

    任何一个对象的创建都包含整个家族簇的创建,任何一个成员的创建,都包含这一整个顺序的完成 通过下面代码理解这个过程

    package study_java.ex01;
    
    public class ExtendsDemo3 {
        public static void main(String[] args){
            // 创建对象
            BMWSportCar mychar = new BMWSportCar();
            mychar.setColor("red");
            mychar.velocity = 200;
            mychar.price = 20000;
            mychar.run();
            System.out.println(mychar.getColor());
    
        }
    }
    
    class Car{
        //私有属性
        private String color;
    
        {
            System.out.println("Cons Block in Car");
        }
    
        public void run(){
            System.out.println("running.....");
        }
    
        public Car(){
    
            System.out.println("new car()");
        }
        // 公有方法
        public String getColor(){
            return color;
        }
        public void setColor(String color){
            this.color = color;
        }
    }
    
    class SportCar extends Car{
        public int velocity;
    
        {
            System.out.println("Cons Block in SportCar");
        }
        public SportCar(){
            System.out.println("new SportCar()");
        }
        public void setColor(String color){
            super.setColor(color);
        }
    
    }
    
    class BMWSportCar extends SportCar{
        public int price;
    
        public BMWSportCar(){
            System.out.println("new BMWSportCar");
        }
    }

    函数覆盖

    子类中出现与父类中一模一样的方法时,会出现覆盖操作,也称为重写或者复写 父类中的私有方法不可以被覆盖 在子类覆盖方法中,继续使用被覆盖的方法可以通过super函数名获取

    覆盖时需要注意的问题: 覆盖时,子类方法权限一定要大于等于父类方法权限 静态只能覆盖静态

    主要的应用是: 当子类需要父类的功能,而功能主题子类有自己特有的内容时,可以复写父类中的方法,这样就既沿袭了父类 的功能,又定义了父类特有的内容

    代码例子:

    package study_java.ex01;
    
    public class OverrideDemo1 {
        public static void main(String[] args){
            Rich2Man s2 = new Rich2Man();
            s2.consume(200000);
        }
    }
    
    class RichMan{
        public void consume(int money){
            if(money < 500){
                System.out.println("消费了"+money+"w");
            }
            else {
                System.out.println("不能消费了");
            }
    
        }
    }
    
    class Rich2Man extends RichMan{
        public void consume(int money){
            if(money < 50000){
                System.out.println("消费了"+money+"w");
            }
            else {
                System.out.println("不能消费了");
            }
    
        }
    }

    子类的实例化过程

    子类中所有的构造函数morning都会访问父类中空参数的构造函数 因为每一个构造函数的第一行都有一条默认的语句super() 子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。 当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数

    final 关键字

    final 可以修饰类,方法和变量

    final 修饰的类不可以被继承

    final 修饰的方法不可以被覆盖(可以继承)

    final 修饰的变量是一个常量只能被赋值一次

    内部类只能访问被final修饰的局部变量

     

    package study_java.ex01;
    
    public class FinalDemo1 {
        public static void main(String[] args){
            Jing8 j = new Jing8();
            j.watch();
            System.out.println(j.name);
        }
    }
    
    class Dog1{
        // 常量
        public final String name = "aaa";
        
        // final 修饰的方法不能重写
        public /*final */ void watch(){
            System.out.println("来人了");
        }
    }
    
    class Jing8 extends Dog1{
        public void watch() {
            System.out.println("听一听");
            super.watch();
        }
    }

    关于内部类 定义在class内部的类 编译产生OuterClass$Innerc.class 内部类访问外部类的局部变量,需要final修饰

    代码例子:

    package study_java.ex01;
    
    public class InnerClassDemo {
        public static void main(String[] args){
            Car2 c = new Car2();
            c.run();
        }
    }
    
    class Car2{
        public String color = "red";
        public int tires;
    
        public void run(){
            new Engine().fire();
            System.out.println("running.....");
        }
    
        class Engine{
            public void fire(){
                System.out.println("fire");
            }
        }
    }

    但是如果内部类写在了方法里,这里有一个问题需要注意:

    public class InnerClassDemo {
        public static void main(String[] args){
            Car2 c = new Car2();
            c.run();
        }
    }
    
    class Car2{
        public String color = "red";
        public int tires;
    
        public void run(){
            // 这里的key必须是final 字段
            final String key = "ss";
            class Engine{
                public void fire(){
                    System.out.println("插入钥匙"+key);
                    System.out.println("fire");
                }
            }
            new Engine().fire();
            System.out.println("running.....");
        }
    
    
    }

    抽象类

    抽象类的定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来 java 中可以定义没有方法体的方法,该方法的具体实现交给子类完成该 方法称为抽象方法,包含抽象方法的类就是抽象类

    抽象类和抽象方法必须用abstract关键字修饰 抽象方法只有方法声明,没有具体的方法体,定义在抽象类中 抽象类不可以被实例化,也就是不能用new创建对象 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的方法后才可以创建对象,否则该子类也是抽象类

     

     

     

     

     

     

  • 相关阅读:
    Java 和 DynamoDB
    关于Mongodb的全面总结
    utf8mb4 使用注意
    mysql 事务隔离讲的比较好的文章收藏。
    [mysql] 常用命令总结
    [JTA] Java事务api
    [Hibernate] Hibernate 参数设置一览表(转)
    Spring配置sessionFactory的几种常用方式
    [前端] org.apache.jasper.JasperException 页面有空引用
    [Hibernate] JPA与Hibernate的优缺点
  • 原文地址:https://www.cnblogs.com/zhaof/p/9257109.html
Copyright © 2020-2023  润新知