Java_2 面向对象

目录

  • 对象
  • 构造方法
  • 引用与对象实例
  • static
  • final
  • 封装
  • 继承
  • 方法重载与重写
  • 多态
  • 抽象类
  • 接口
  • 内部类


Java是面向对象的高级语言,类和对象是Java程序的核心。

类和对象

当我们买一部手机时,需要的是内存大一点、运行速度快一点、像素高一点等等,它是对象么?
不是,它是一个类。
当我们买了一部华为时,它就是一个对象。对象是具体的、确定的物体。
这部手机的颜色、尺寸、编号等是它的属性;我们使用手机来打电话、发短信的行为是它的“方法”。

  • 创建类
    类,是具有相同属性和方法的对象的集合。

    public class 类名{
    // 属性(成员变量)
    属性类型1 属性命1;
    ...
    
    // 方法
    方法1;
    ...
    

    一个类可以包含以下类型变量:
    局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
    成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
    类变量:也叫静态变量,类变量也声明在类中,方法体之外,但必须声明为 static 类型。

  • 创建对象
    创建类时,不会开辟内存进行存储。当创建对象时,才开辟内存存储属性和方法。

    类名 对象名 = new 类名();
    
    // Test.java
    public class Test{
    	// 属性(成员变量)
        double height;
        int age;
        int sex;  // 性别,0为男;非0为女
    	// 方法
        void laugh(){
            System.out.println("我有笑");
        }
        void printBaseMes(){
            System.out.println("我的身高是:" + height);
            System.out.println("年龄:" + age);
            if (this.sex == 0){
                System.out.println("男");
            }
            else{
                System.out.println("女");
            }
        }
    }
    // NewObj.java
    public class NewObj{
        public static void main(String[] args){
            Test test = new Test();
    
            test.height = 170;
            test.age = 20;
            test.sex = 0;
    
            test.printBaseMes();
        }
    }
    

    关于对象中各变量的作用域:
    1.局部变量的作用域仅限于定义它的方法内。而成员变量的作用域在整个类内部都是可见的。
    2.同时在相同的方法中,不能有同名的局部变量;在不同的方法中,可以有同名的局部变量。
    3.成员变量和局部变量同名时,局部变量具有更高的优先级。

构造方法

  • 每个类至少会生成一个构造方法
    1.构造方法名称与类名相同,没有返回值。
    2.如定义类时如未定义构造方法,系统自动生成无参构造方法;如定义,则不再自动生成。

    // Test1.java
    public class Test1{
        double height;
        int age;
    
        public Test1(double h, int a){
            height = h;
            age = a;
        }
    
        void print(){
            System.out.println("我的身高:" + height);
            System.out.println("我的年龄:" + age);
        }
    }
    
    // NewObj.java
    public class NewObj{	
        public static void main(String[] args){
            Test1 t1 = new Test1(170, 22);
            t1.print();
        }
    }
    

    3.构造方法的重载:可以定义多个构造方法,使用时系统据给定的不同参数自动选择相应的构造方法。

    // Test1.java
    public class Test1{
        double height;
        int age;
        int sex;  // 性别,0为男,非0为女
    
        public Test1(double h, int a){
            height = h;
            age = a;
        }
        public Test1(int s){
            sex = s;
        }
    
    
        void print(){
            System.out.println("我的身高:" + height);
            System.out.println("我的年龄:" + age);
        }
        void printSex(){
            if (sex == 0){
                System.out.println("男");
            }
            else{
                System.out.println("女");
            }
        }
    }
    
    // NewObj.java
    public class NewObj{
        public static void main(String[] args){
            Test1 t1 = new Test1(170, 22);
            t1.print();
            Test1 t2 = new Test1(0);
            t2.printSex();
        }
    }
    

引用与对象实例

当Java新建一个对象时,只是创建了一种引用,类似于c语言中的指针,指向内存中存储数据的地址。

static

  • 静态成员(或类成员)
    // Static.java
    public class Static{
        public static String str = "shiyan";
        public String str1 = "test";
        public static void main(String[] args){
        	// 静态成员,不需要实例化可以直接通过类名访问
            System.out.println(Static.str);
    		// 非静态成员,必须实例化后才可访问
            Static str2= new Static();
            System.out.println(str2.str1);
        }
    }
    
  • 静态方法
    不需要实例化即可调用。
    不能使用关键字this,不能访问非静态成员和非静态方法。

final

final 修饰类,则该类不允许被继承,为最终类
final 修饰方法,则该方法不允许被覆盖(重写)
final 修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值(但只能选其一)
final 修饰变量,则该变量的值只能赋一次值,即常量

public final static String Test = "test";

封装

隐藏对象的属性和实现细节,仅对外公开接口,并控制对象属性的读和修改的权限。

  • 权限修饰符
访问修饰符本类同包子类其它
private1
默认11
protected111
public1111
  • getter/setter
    对外提供的每个属性读写的公共访问方法。并在getter/setter中加入判断语句,否定非法输入。
// Test1.java
public class Test1{
    private double height;
    public double getHeight(){
        return height;
    }
    public void setHeight(double newHeight){
        height = newHeight;
    }
}

// NewObj.java
public class NewObj{
    public static void main(String[] args){
        Test1 t1 = new Test1();
        t1.setHeight(177);
        System.out.println(t1.getHeight());
    }
}
  • this
    代表当前对象。
    当成员变量与局部变量相同时,局部变量优先级更高。如需访问成员变量,使用this.属性。方法亦同。

继承

解决代码复用的问题。

class 子类 extends 父类

子类拥有父类除private以外的所有属性和方法;
子类可以有自己的属性和方法;
子类可以重写父类的方法;
Java中的继承是单继承,一个类只有一个你类。
补:Java实现多继承的方法implements接口。

// Animal.java
public class Animal{
    public int legNum;

    public void bark(){
        System.out.println("叫");
    }
}

// Dog.java
public class Dog extends Animal{
}

// Test.java
public class Test{
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.legNum = 4;
        dog.bark();
    }
}
  • super
    在子类内部使用,代表父类对象。
    1.父类属性:super.属性
    2.父类方法:super.bark()
    3.子类构造方法需要调用父类的构造方法时,在子类构造方法体最前面加上:super()

方法重载与重写

  • 方法重载
    一个类中可以定义多个同名的方法,但每个方法的参数类型或参数个数都不一样。

方法中的参数列表必须不同。比如:参数个数不同或者参数类型不同。
重载的方法中允许抛出不同的异常
可以有不同的返回值类型,但是参数列表必须不同
可以有不同的访问修饰符

public class Test{
    void f(int i){
        System.out.println(i);
    }
    void f(double d){
        System.out.println(d);
    }
    void f(String s1, String s2){
        System.out.println(s1 + s2);
    }
    void f(String s, int i){
        System.out.println(s + ", " + i);
    }

    public static void main(String[] args){
        Test t = new Test();
        t.f(0);
        t.f(1.0);
        t.f("I", "love u");
        t.f("I", 4);
    }
}
  • 方法重写
    子类继承父类的方法后,可以方法进行重写。
// Animal.java
public class Animal{
    void bark(){
        System.out.println("叫");
    }
}

// Dog.java
public class Dog extends Animal{
	// 重写
    void bark(){
        System.out.println("汪");
    }
}

// Test.java
public class Test{
    public static void main(String[] args){
        Animal ani = new Animal();
        Dog dog = new Dog();
        ani.bark();
        dog.bark();
    }
}

多态

又称动态绑定。
同一消息,发送给不同的对象,产生不同的行为。

  • 向上转型
    子类可以自动向上转型为父类。反之,不行。
public class Test{

    public static void main(String[] args){
    	// Dog -> Animal
    	// 遗忘子类中与父类不同的方法,重写与父类相同的方法
        Animal ad = new Dog();
        ad.bark();
    }
}
  • 多态的实现条件:继承、重写、向上转型
  • 多态的实现方式
    1.继承父类进行方法重写
    2.抽象类和抽象方法
    3.接口实现

抽象类

抽象类的实现规则:
用 abstract 修饰符定义抽象类
用 abstract 修饰符定义抽象方法,只用声明,不需要实现
包含抽象方法的类就是抽象类
抽象类中可以包含普通的方法,也可以没有抽象方法
抽象类的对象不能直接创建,通常是定义引用变量指向子类对象。

使用抽象类:
1.自上而下的设计时,只需知道父类需要实现哪些功能,不需关心子类具体的实现方式;
2.从多个类中抽象出子类模版。

// TelePhone.java
public abstract class TelePhone{
    public abstract void call();
    public abstract void message();
}

// CellPhone.java
public class CellPhone extends TelePhone{

    @Override
    public void call(){
        System.out.println("打电话");
    }
    @Override
    public void message(){
        System.out.println("发短信");
    }

    public static void main(String[] args){
        CellPhone c = new CellPhone();
        c.call();
        c.message();
    }
}

接口

用于描述类所具有的功能,而不提供实现的方式。

修饰符 interface 接口名称 [extends 其它接口名]{
	// 声明变量
	// 抽象方法
}

// 多继承实现方式
修饰符 interface A extends 接口1,接口2{
}

修饰符 class A implements 接口1, 接口2{
}
// Animal.java
interface Animal{
    int y = 7;
    public void eat();
    public void run();
}

// Dog.java
public class Dog implements Animal{

    public void eat(){
        System.out.println("Dog eat");
    }
    public void run(){
        System.out.println("Dog run");
    }
    public static void main(String[] args){
        Dog d = new Dog();
        System.out.println(d.y);
        d.eat();
        d.run();
    }
}

内部类

将一个类定义到另一个类的内部。与之对应的类为外部类。作用:
1.更好的封装;
2.内部类可以访问外部类的所有变量;
3.有些功能使用内部类可以更好的实现;
4.内部类允许继承多个非接口类型。

内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为 outer 的外部类和其内部定义的名为 inner 的内部类。编译完成后出现 outer.class 和 outer$inner.class 两类。所以内部类的成员变量/方法名可以和外部类的相同。

  • 成员内部类
// Animal.java
public class Animal{
    private int ID = 0;
    // 内部类 Dog
    public class Dog{
        String name = "dog";
        public void bark(){
            System.out.println("汪");
        }
    }

    public static void main(String[] args){
        Animal ani = new Animal();
        Dog dog = ani.new Dog();
        dog.bark();
    }
}

1.Dog相当于Animal的一个成员变量;
2.Dog的方法可以访问Animal的所有属性和方法;
3.成员内部类的实例化:内部类 对象名 = 外部类.new 内部类();
4.如内部类与外部类有相同属性或方法,内部类默认优先访问内部类的属性或方法。如需访问外部类的属性或方法,使用this关键字;
5.成员内部类不能含有 static 的变量和方法,因为成员内部类需要先创建了外部类,才能创建它自己。

  • 静态内部类
    嵌入类。
// Animal.java
public class Animal{

    private int legNum = 4;
    static String ID = "20200001";
    static int age = 3;

    public static class Dog{
        String ID = "20200002";
        public void printInfo(){
            System.out.println("Dog ID:" + ID);
            System.out.println("Animal age:" + age);
            System.out.println("Animal ID:" + Animal.ID);
            System.out.println("Animal legNum:" + new Animal().legNum);
        }
    }

    public static void main(String[] args){
        Dog dog = new Dog();
        dog.printInfo();
    }
}

1.静态内部类成员名与外部静态成员名相同时,静态内部类优先访问自身的成员:成员
2.外部类的静态成员名与静态内部类不同名时,静态内部类可直接访问:成员
3.静态内部类访问外部类的静态成员:外部类名.静态成员
4.静态内部类访问外部类的非静态成员:new 外部类().成员
5.静态内部类可以直接实例化:静态内部类 对象 = new 静态内部类().

  • 局部内部类
    内部类定义在方法和作用域内。
// Animal.java
public class Animal{

    // 定义在方法内
    public void printInfo(){
        final String NAME = "Animal";
        class Dog{
            String ID = "20200002";
            public void print(){
                System.out.println("Dog ID:" + ID);
                System.out.println("printInfo() NAME:" + NAME);
            }
        }
        Dog dog = new Dog();
        dog.print();
    }
    // 定义在作用域内
    public void printInfo2(boolean b){
        if (b){
            final String NAME = "Animal_";
            class Dog{
                String ID = "20200002_";
                public void print(){
                    System.out.println("Dog ID:" + ID);
                    System.out.println("printInfo2() NAME:" + NAME);
                }
            }
            Dog dog = new Dog();
            dog.print();
        }
    }
    // test
    public static void main(String[] args){
        Animal ani = new Animal();
        // 方法内
        ani.printInfo();
        // 作用域内
        ani.printInfo2(true);
    }
}

如何理解定义在作用域内?

  • 匿名内部类
    没有名字的内部类,只能使用一次,通常用来简化代码。
    使用前提:必须继承一个父类,或实现一个接口
// Outer.java
public class Outer{

    public Inner getInner(final String name, String city){
        return new Inner(){
            private String nameStr = name;
            public String getName(){
                return nameStr;
            }
        };
    }

    public static void main(String[] args){
        Outer outer = new Outer();
        Inner inner = outer.getInner("Inner", "NewYork");
        System.out.println(inner.getName());
    }
}
interface Inner{
    String getName();
}

1.匿名类不能加访问修饰符;
2.new 匿名类(),要先定义,否则会报错;
3.当所匿名类所在方法的形参需要在匿名类内部使用时,必需使用final

// 因匿名内部类无名字,默认无参构造函数
// 带参构造函数的实现
    public Inner getInner(final String name, string city){
        return new Inner(name, city){
            private String nameStr = name;
            public String getName(){
                return nameStr;
            }
        };
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值