JavaSE--面向对象篇

JavaSE–面向对象篇

这里写图片描述

1.面向对象的特征以及与面向过程的区别

面向对象的特征:
1.抽象:从特定角度出发,从已经存在的一些事物中抽取我们所关注的特性。
2.封装:隐藏对象的属性和实现细节,仅仅对外公开接口。
3.继承:子类可以继承父类的所用成员变量与方法。
4.多态:多态是指允许不同类的对象对同一消息作出响应。

面向对象与面向过程的区别:
面向过程
概念
面向过程是一种以过程为中心的编程思想,它是一种基础的顺序的思维方式,面向对象方法的基础实现中也包含面向过程思想。
特性:模块化 流程化
优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开 发,性能是最重要的因素。
缺点:没有面向对象易维护、易复用、易扩展

面向对象
概念
面向对象是按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设计、实现软件的办法。通过面向对象的理念使计算机软件系统能与现实世界中的系统一一对应。
特性:抽象 封装 继承 多态
优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点:性能比面向过程低

2.内存空间

这里写图片描述

3.类的定义

public class 类名 (extends 父类) (implements [接口]){
    private int id;//成员变量
    public void fun1(){}//成员方法
    ...
}

4.new操作与构造方法

public class Person {
    private int id;
    private int age;
    Person(int id, int age){
        this.id=id;
        this.age=age;
    }
}
public static void main(String[] args){
    Person p = new Person(120);
}

构造方法:与类同名,不能有返回值,void也不行!

new Person(1,20)会调用Person类相应的构造方法,在堆区创建相应的对象。

注意:Person p = new Person(1, 20);相当于两句:

Person p;//先声明一个p
p = new Person(120);

所以,正确的应该是:
(零)调用Person构造方法之前,先在栈中创建一个Person类型的p,值为空null;
①然后调用Person构造方法在堆区创建一个Person对象,以及栈区创建形参id,age的临时变量,传递实参为形参赋值;
这里写图片描述
②进入构造方法的方法体,this.id=id,相当于,形参id为该对象的id赋值为1;同理,形参age也为age赋值为20;
这里写图片描述

5.对象创建和引用

③接着退出构造方法,局部变量(形参)id,age销毁,这时候栈中的p指向堆区的Person对象(p引用Person对象,p就获得一个地址值,该地址值执行Person对象),完成对象的创建;
这里写图片描述

6.this:

this代表使用该方法的对象的引用,其值为当前对象的引用;
例如:new Person(1,20)调用了Person的构造方法,所以this的值为这个对象的引用,指向这只新new出来的Person(1,20)对象;

7.static

public class Person {
    private int id;
    private int age;
    private static sid = 100;
    Person(int id, int age){
        this.id=id;
        this.age=age;
        sid++;
    }
}
public static void main(String[] args){
    Person p = new Person(120);
}

对象里有static成员变量,会在data seg创建sid=100,并且自增1,被所有Person的实例共享;

这里写图片描述

注意
①在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份;
②用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以static方法中不可访问非static的成员(静态方法不再是针对于某个对象调用,所以不能访问非静态成员)(在static方法中new一个p,然后在p.xxx这当然可以);
③可以通过对象引用或类名(类名的不需要实例化)访问静态成员和方法;

8.package与import:

package:
项目资源.公司域名.com名倒过来com.公司域名.项目资源
import:
导包,导入后就无须写全路径的类名了;

9.访问修饰符:

访问修饰符类内部同一个包中子类所有地方
private
default
protected
public

注意:
①dafault表示默认,实质上没有访问控制修饰符,所以不用写default关键字来修饰。
②public protected 默认(不写修饰符就代表默认) private 修饰类的成员(方法),用来限定其他对象对其的访问权限;
③对于class的权限修饰只能用public和default,不写就为默认;

10.继承、super与继承中的构造方法:

public class Person {
    private int id;
    private int age;
    Person(int id, int age){
        this.id=id;
        this.age=age;
    }
}
public class Student extends Person {
    private String school;
    Student(int id, int age, String school){
        super();
        this.school=school;
    }
}
public static void main(String[] args){
    Student s = new Student(2, 20, "sch");
}

(零)在调用构造方法之前,在栈区创建Student类型的s变量,值为空null;
①new Student(2, 20, “sch”)调用Student的构造方法,在栈中创建Student方法的局部变量(形参)id,age,school,堆中创建Student对象,data seg创建字符串“sch”,school指向“sch”,id赋值为2,age赋值为20;
这里写图片描述

②super();调用父类的构造方法

    Person(int id, int age){
        this.id=id;
        this.age=age;
    }

这时,又在栈区创建Person方法的局部变量(形参)id,age,并赋值,同时在堆区中的那个Student对象中创建Person对象;
这里写图片描述

③super();执行完毕,销毁局部变量age,id,返回到this.school=school;这时,调用为堆中的school引用“sch”;
这里写图片描述

④执行完回到Student s = new Student(2, 20, “sch”);销毁局部变量school,age,id,并且为栈区创建Student类型的s指向堆区中的Student对象(值为未知地址,地址指向Student对象),完成new操作;
这里写图片描述

注意:
①通过继承,子类自动拥有了基类的所有成员(成员变量和方法);
②Java只支持单继承,不允许多继承(一个子类只能有一个基类,一个基类可以派生出多个子类);
③继承的内存分析中,子类中包含了一个父类对象,super指向该父类对象,this指向调用该方法的对象;

继承中的构造方法:
①子类的构造的过程中必须调用其基类的构造方法;
②子类可以在自己的构造方法中使用super(..)调用基类的构造方法(其中,this(..)调用本类中的另外的构造方法);
③如果子类的构造方法中没有显试地调用基类的构造方法(super(..)调用),则系统默认调用基类无参数的构造方法;
④如果子类构造方法既没有显式调用基类构造方法,基类中又没有无参的构造方法,则编译错误

11.重载与重写

重载
①是指一个类中可以定义有相同名字,但参数不同(参数个数,类型,顺序不同)的多个方法,调用时,会根据不同的参数选择对应的方法。
②注意:返回值类型不同不算重载,因为可以不用返回值,以致于程序没办法区分到底运行哪个方法;
③总结:在一个类中,能够达到完全区分开来的同名方法,就为重载;

重写
①是指在子类中可以根据需要对从基类中继承来的方法进行重写,重写方法必须和被重写方法具有相同的方法名称、参数列表和返回类型(就是声明那里一模一样(异常抛出除外))。
②注意:重写方法不能使用比被重写方法更严格的访问权限。
③总结:重写父类方法时,为防止错写,最好复制父类该方法的声明。

12.Object类:所有类的根基类

public String toString()方法 :
①描述当前对象的有关信息;默认打印以下内容:
这里写图片描述
②在进行String与其它类型数据的连接操作(如:System.out.println(“info0”+person)),将自动调用该对象类的toString方法;
③可以根据需要重写toString()方法。

public boolean equals(Object obj)方法:
①判断对象是否“相等”;默认的判断规则相当于“==”(==是判断内存地址是否一样),equals判断是否引用同样一个对象;
②如String、Date等重写了Object的equals方法,调用该方法时,判断规则为:如果引用的是同一类对象(不一定是同一个对象)且属性内容相等时返回true,否则返回false;
③可以根据需要重写equals方法;

13.对象转型:

向上转型:子类的对象可以当作基类的对象来使用;

public class Person{...}
public class Student extends Person {...}
Person s = new Student();//向上转型
Student s1 = (Student) s;//向下转型

这里写图片描述
向下转型:基类的对象可以当作子类的对象来使用,也称为强制类型转换
这里写图片描述
Person s把引用赋值给Student s1,使得s1获得了Student的引用,然后s销毁;

注意:
①一个基类的引用类型变量可以在指向其子类的对象;
②一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)(Person s只是把Student当作Person来处理,也只能调用Student已经重写了的父类的方法);
③使用 引用 变量 instanceof 类名 来判断引用型变量所指向的对象是否属于该类或该类的子类

14.多态(面向对象的核心):

多态也叫动态绑定,迟绑定,是指:在执行期间(而非编译期间)判断所引用对象的实际类型,根据其实际类型调用其相应的方法。

实现动态绑定的三个条件:
①要有继承;
②要有重写;
③父类型引用指向子类对象;
其中有两种实现形式:
一、形参:

public class Person{
    ...
    public void sing(){
        System.out.println("在唱歌...");
    }
}
public class Student extends Person {//继承父类
    ...
    public void sing(){//重写父类方法
        System.out.println("学生在唱歌...");
    }
}
public class Singer {
    ...
    public void whoSing(Person p) {//如果传递的实参是个子类,那么就满足父类型指向子类对象的条件
        p.sing();
    }
}
@Test
public void fun1(){
    Student student = new Student(); 
    Singer singer = new Singer();
    singer.whoSing(student);
}

这里写图片描述
singer.whoSing(student);//这时,控制台打印“学生在唱歌…”
之所以打印“学生在唱歌…”,而不是打印局部变量p的方法:“在唱歌…”,是因为实现了动态绑定,根据实际的类型来调用其相应类型的方法(这里实际类型是Student,所以调用Student的sing方法);

二、对象转型

public class Person{
    ...
    public void sing(){
        System.out.println("在唱歌...");
    }
}
public class Student extends Person {//继承父类
    ...
    public void sing(){//重写父类方法
        System.out.println("学生在唱歌...");
    }
    public void print(){//重写父类方法
        System.out.println("学生在画画...");
    }
}

@Test
public void fun1(){
    Person student = new Student(); //向上转型,实现父类型指向子类对象
    student.sing();//打印“学生在唱歌...”,实现动态绑定
    Student s = (Student) student;//向下转型
    s.print();//打印“学生在画画...”
}

这里写图片描述
student.sing();//打印“学生在唱歌…”:是因为,父类型指向了Student对象,满足了条件三,这样动态绑定的三个条件满足,所以就就打印出“学生在唱歌”,实现动态绑定;
而变量student现在是调用不了print方法的,因为student声明为了Person类型,只把他当成了Person来处理,Person中没有print方法。
这里写图片描述
这时,如果把Person student向下转型为Student类型,就看的见print方法,调print方法s.print();就可以打印出“学生在画画”。

15.抽象类:

①用abstract修饰的类叫做抽象类,用abstract修饰的方法叫做抽象方法;
②含有抽象方法的类必须被声明为抽象类,抽象类不能被实例化,必须被继承,且抽象方法必须被重写。
③抽象方法只需声明,不需实现。

16.final

①final的变量(成员变量、局部变量)的值不能够被改变,表示常量;
②final的方法不能够被重写;
③final的类不能够被继承;

17.接口

接口(interface)是抽象方法和常量值的定义的集合。从本质商家爱那个,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
举例:

public interface Singer {
    public static final int id = 1;
    public void whoSing();
}

其中:
①多个无关的类可以实现同一个接口;
②一个类可以实现多个无关的接口;
③与继承关系类似,接口与实现类之间存在多态性;

接口的特性:
①接口可以多重实现;
②接口中声明的属性默认为public static final 的(也只能是)(这样可以解决c++中多重继承的问题);
③接口中只能定义抽象方法,而且这些方法默认为public(也只能是);
④接口可以继承其他的接口,相当于添加新的属性和抽象方法;

接口内存分析:

public interface Singer {
    ...
    public void whoSing();
}
public class Student implements Singer {
    ...
    public void whoSing(){//实现接口方法
        System.out.println("学生在唱歌...");
    }
    public void whoSleep(){
        System.out.println("学生在睡觉...");
    }
}
@Test
public void fun1(){
    Singer s = new Student();
    s.whoSing();//站在Singer的角度,只能访问到whoSing方法 
    Student s1 = (Student) s;
    s1.whoSleep();//站在Student的角度就能够访问到whoSleep方法
}

这里写图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值