面向对象(上)

一,对象的创建

        对象就是类实例化的结果,要创建对象就要先有一个类,先创建一个狗类。

public class Dog {
    // 约束了什么类型的属性
    String color;
    int age;
    String name;
}

        类创建完毕之后就可以创建对象了,和对对象内的属性进行复制操作了  

         // 创建对象
        // 类名 变量名(对象名) = new 类名();
        // 对象名.属性名 = 属性值;

 public static void main(String[] args) {
        
        // 创建对象
        // 类名 变量名(对象名) = new 类名();
        // 对象名.属性名 = 属性值;
        Dog dog = new Dog();
        dog.color = "黄色";
        dog.name = "旺财";
        dog.age = 12;
        System.out.println(dog.color);
        System.out.println(dog.age);
        System.out.println(dog.name);

    }

二,对象内部的细节

        属性 

        在刚刚创建的狗的对象里面color,age,name叫做对象的属性,这里用了默认的修饰符。对于属性的修饰符有多种,修饰权限从小到大是 private,默认,protect,public。访问关系如下

 

        方法 

        类(对象)中的方法分为多种,如果是使用private来修饰为了外部可以访问,就衍生了出了setter,getter方法,这二种方法,然后就是一些其他的方法,普通方法,构造器。方法和属性一样,同样可以被修饰符来做限制,限制外部是否可以访问我的方法,或者构造器,注意了因为 setter,getter方法是为了让外部可以访问的,所以一定是public修饰,在编译器里面一般用快捷键生成。构造器也是可以通过快捷键快速生成的。
 

package com.haogu.pojo;

public class Animal {
    public String name;
    public int age;
    private String color;
//构造器重载
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
//构造器

    public Animal() {
    }
//普通方法
    public void eat(){
        System.out.println("动物" + this.name + "正在吃东西");
    }
//一下全是set get方法

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

这里面需要注意的是,构造器的构成 是必须 修饰符+方法名称(名称一定和类相同),普通方法是 修饰符+返回值+方法名
既然提到了重载就说明一下,重载和重写的区别,后续说到重写会再次说明的

重载: 发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。

重写: 发生在父子类中,方法名.参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。
构造器只能重载不能被重写

构造器的作用

        有了构造器之后我们可以再创建对象的时候就对属性赋值,而不是需要使用,对象名称.属性的方式来赋值,注意传入的参数要和你构造的参数类型相对于

public static void main(String[] args) {

        Animal animal = new Animal("老虎",18);
        System.out.println(animal.name);
        System.out.println(animal.age);
    }



 

 方法的调用 

                类名.方法名称
 

  public static void main(String[] args) {

        Animal animal = new Animal("老虎",18);
        System.out.println(animal.name);
        System.out.println(animal.age);
        animal.eat();
    }

三,对象的特点 

1,封装

        就是把对象的属性和行为(数据)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西隐藏起来,把可以告诉别人的公开,别人只能用我提供的功能实现需求,而不知道是如何实现的。增加安全性。
我们创建的类就是封装,里面的属性和方法就是这个类的行为,拿上面例子来讲,我有一个动物类,动物都是有分类,年龄和行为的,我把他们写在一个类中就是封装,

2,继承 

特点:单继承,一个类只能继承一个父类,一个父类可以有多个子类

        子类继承父类的数据属性和行为,并能根据自己的需求扩展出新的行为,提 高了代码的复用性。

public class Cat extends Animal{
 private String type;
    @Override
    public void eat(){

        System.out.println("猫吃老鼠");
    }
    public void catchMouse(){
        System.out.println( this.name + "抓老鼠");
    }
}

我的例子里面继承了动物类,就代表我拥有动物类中的一切共有 属性和方法,并且我可以再他的基础上做出扩展,里面的type与抓老鼠方法就是做出的扩展,而eat方法是我对父类方法的重写。
重写只发生在父子类中,而重载只发生在一个类中

3,多态

        指允许不同的对象对同一消息做出响应。即同一消息可以根据发送对象的不 同而采用多种不同的行为方式(发送消息就是函数调用)。封装和继承几乎都是为多态而准 备的,在执行期间判断引用对象的实际类型,根据其实际的类型调用其相应的方法。

        个人认为多态最主要的体现就是,里氏代换原则(23中设计模式的设计原则),它强调子类应该能够替换掉它们的基类(父类),并且程序的行为不会改变。也就是说,任何使用基类(父类)对象的地方,都应该能够透明地使用其子类对象,而不会产生错误或不正确的行为。 

四,关于对象特点的一些关键字

1.this和super的意义

this:当前对象

  • 在构造器和非静态代码块中,表示正在new的对象

  • 在实例方法中,表示调用当前方法的对象

super:引用父类声明的成员

无论是this和super都是和对象有关的。

2.this和super的使用格式
  • this

    • this.成员变量:表示当前对象的某个成员变量,而不是局部变量

    • this.成员方法:表示当前对象的某个成员方法,完全可以省略this.

    • this()或this(实参列表):调用另一个构造器协助当前对象的实例化,只能在构造器首行,只会找本类的构造器,找不到就报错

  • super

    • super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的

    • super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的

    • super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错

3.避免子类和父类声明重名的成员变量

特别说明:应该避免子类声明和父类重名的成员变量

因为,子类会继承父类所有的成员变量,所以:

  • 如果重名的成员变量表示相同的意义,就无需重复声明

  • 如果重名的成员变量表示不同的意义,会引起歧义

在阿里的开发规范等文档中都做出明确说明

4.解决成员变量重名问题
  • 如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别

  • 如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量

  • 如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问

   

class Father{
	int a = 10;
	int b = 11;
}
class Son extends Father{
	int a = 20;
    
    public void test(){
		//子类与父类的属性同名,子类对象中就有两个a
		System.out.println("子类的a:" + a);//20  先找局部变量找,没有再从本类成员变量找
        System.out.println("子类的a:" + this.a);//20   先从本类成员变量找
        System.out.println("父类的a:" + super.a);//10    直接从父类成员变量找
		
		//子类与父类的属性不同名,是同一个b
		System.out.println("b = " + b);//11  先找局部变量找,没有再从本类成员变量找,没有再从父类找
		System.out.println("b = " + this.b);//11   先从本类成员变量找,没有再从父类找
		System.out.println("b = " + super.b);//11  直接从父类局部变量找
	}
	
	public void method(int a, int b){
		//子类与父类的属性同名,子类对象中就有两个成员变量a,此时方法中还有一个局部变量a		
		System.out.println("局部变量的a:" + a);//30  先找局部变量
        System.out.println("子类的a:" + this.a);//20  先从本类成员变量找
        System.out.println("父类的a:" + super.a);//10  直接从父类成员变量找

        System.out.println("b = " + b);//13  先找局部变量
		System.out.println("b = " + this.b);//11  先从本类成员变量找
		System.out.println("b = " + super.b);//11  直接从父类局部变量找
    }
}
class Test{
    public static void main(String[] args){
        Son son = new Son();
		son.test();
		son.method(30,13);  
    }
}
5,final关键字

修饰类:表示类不可被继承,修饰方法,表示方法不可被重写,修饰变量:变量一旦被复制就不能被修改了;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值