Java面向对象
比较下面向过程与面向对象
面向过程:C 语言。做一件事情的时候,“我该怎么做?”。需要思考比较详细的步骤,按着步骤一步步来实现。需要关心实现的每一个细节,以及资源持有的对象。
面向对象:Java 语言。做一件事情的时候,“我应该找谁来做?”。不需要我们太过关心这件事怎么去实现,只需要指定对应的对象即可。因为对象已经具备对应的技能,指定了的对象会自己通过它的技能去实现对应的功能。
面向对象编程思想实际上就是一种运用对象、类、继承、封装、聚合、关联、消息、多态性等概念来构造系统的软件开发方法。
好处:1)面向对象思维方式是一种更加符合人们日常中思考的习惯。
2)面向对象中更多的会体现出调用者的处理能力。
3)可以将复杂的问题,封装起来,更加有条理去处理。
类与对象
类,用于描述多个对象的共同特征,它是对象的模板。
对象,用于描述现实中的个体,它是类的实例。
类的定义:使用关键字 class 来定义 java 中的类
◆ 格式:
class 类名 {
//属性
数据类型 变量名;
//方法
修饰符 返回值类型 方法名(参数){ }
}
类:手机。很有钱,买 iphoneX
方法:炫耀、打电话、微信、拍照、听歌、看视频、游戏……
属性:显示屏、电池、蓝牙、陀螺仪、摄像头、扩音器……
// 定义一个类
public class 类名 {
// 定义字段 field
int a = 1;
// 定义方法(无返回值)
public void getName(){
}
// 定义方法(有返回值)
public String getName(){
return “”;
}
}
// 类的使用:如果你要用它,必须要拿到一个类的实例。(跟Scanner、Random类一样使用前进行实例化Scanner scan=new Scanner();...)
// 其实,就是我们需要将类放到堆内存中,别人才可以拿来用。
// 只要你使用一个 new 关键字,就可以在堆内存中开辟一个空间,存放类的实例。
类类型 变量名 = new 类名();
// 类类型:其实就是类名,只不过此处只是用来声明变量的类型而已,跟外界说,当前变量的类型是和我某个类的类型一致的。
User user = new User();√√(只要是类,都这样用)
创建对象:
◆ 格式:
类名 对象名 = new 类名();
如果要实现某些功能的话,至少要包含方法。
如果有一些固定或者变动的值需要拿来处理,则可以使用属性进行定义。
创建对象的原理:
在实例化一个对象时,同时操作了栈内存和堆内存。
①在栈内存保存对象的首地址,即引用;
②在堆内存中保存了对象的属性。
对对象的所有操作只能通过引用完成,一旦引用出栈释放没有任何引用指向该对象,对象就变成垃圾失效。
面向对象的特点------封装,继承,多态
概念:封装(private 关键字)
封装,把对象的属性与方法的实现细节隐藏,仅对外提供一些公共的访问方式
使用封装的步骤:
1、将类的所有属性使用关键字private去修饰,把它们变成私有的,不允许外部类直接访问
2、生成或者提供公共的setter/getter方法去操作这些被隐藏起来的属性(不再是直接对属性进行操作了)
3、在类自己的 setter/getter方法中加入逻辑控制,以确保数据访问的有效性和安全性
private 关键字,私有的意思
◆ 它可以用来修饰类中的成员(成员变量,成员方法)
◆ private 的特点:
private 修饰的成员只能在当前类中访问,其他类中无法直接访问
this 关键字
this 关键字,本类对象的引用
◆ this 是在方法中使用的,哪个对象调用了该方法,那么,this 就代表调用该方法的对象引用
◆ this 什么时候存在的?当创建对象的时候,this 存在的
◆ this 的作用:用来区别同名的成员变量与局部变量(this.成员变量)
public void setName(String name) {
this.name = name;
}
定义一个user类、bus类,实现封装调用
package com.hello.fengzhuang;
public class User {
//复习类的封装
//定义类的字段
private String name;
private int age;
//定义获取名字的方法
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 void sitBus()
{
System.out.println("叫"+ name +"的那个同学坐上了388公交,"+"听说小姐姐今年"+ age +"岁了...");
}
}
另一个类
public class Bus {
//复习类的封装
//定义类的字段以及方法
private String name;
private int age;
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 void run() {
System.out.println("哈哈哈,你看我多快");
}
public void openDoor() {
System.out.println("车开门了");
}
public void closeDoor() {
System.out.println("车又关门了");
}
public void stop() {
System.out.println("哈哈哈,我要停车了");
}
public void shangche(String name) {
System.out.println(name+"上车了");
}
}
测试类
package com.hello.fengzhuang;
import org.junit.Test;
public class Demo {
//复习类的封装
//调用这些方法
@Test
public void test() {
User user=new User();//使用的时候实例化User
user.setName("小花");
user.setAge(20);
Bus bus=new Bus();//使用的时候实例化Bus
bus.run();
bus.openDoor();
bus.shangche(user.getName());//不是user.name()了,而是调用它的getname()方法
bus.closeDoor();
bus.stop();
user.sitBus();
}
}
继承
概念:继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
在程序中,如果想声明一个类继承另一个类,需要使用 extends 关键字。子类又被称为派生类; 父类又被称为超类(Super Class)。
格式:
class 子类 extends 父类 { }
接下来通过一个案例来学习子类是如何继承父类的,如下所示。
/* 定义员工类 Employee */
class Employee {
String name; // 定义 name 属性
// 定义员工的工作方法
public void work() {
System.out.println("尽心尽力地工作");
}
}
研发部员工类 Developer
/* 定义研发部员工类 Developer 继承 员工类 Employee */
class Developer extends Employee {
// 定义一个打印 name 的方法
public void printName() {
System.out.println("name=" + name);
}
}
/* 定义测试类 */
public class Example01 {
public static void main(String[] args) {
Developer d = new Developer(); // 创建一个研发部员工类对象
d.name = "小明"; // 为该员工类的 name 属性进行赋值
d.printName(); // 调用该员工的 printName()方法
d.work(); // 调用 Developer 类继承来的 work()方法
}
}
使用:直接给子类实例化
继承的好处:
1、继承的出现提高了代码的复用性,提高软件开发效率。
2、继承的出现让类与类之间产生了关系,提供了多态的前提。
继承的限制
限制一:一个子类只能够继承一个父类,存在单继承局限。
错误的写法:
class A { }
class B { }
class C extends A,B { } // 一个子类继承了两个父类
正确的写法:
class A {}
class B extends A {}
class C extends B {}
C实际上是属于(孙)子类,这样一来就相当于B类继承了A类的全部方法,而C类又继承了A和B类的方法,这种操作称为多层继承。
结论:Java之中只允许多层继承,不允许多重继承,Java存在单继承局限。
限制二:在一个子类继承的时候,实际上会继承父类之中的所有操作(属性、方法),但是需要注意的是,对于所有的非私有(no private)操作属于显式继承(可以直接利用对象操作),而所有的私有操作属于隐式继承(间接完成set get)。
限制三:在继承关系之中,实例化的是子类对象,但是发现它会默认先执行父类构造函数(方法),调用父类构造的方法体执行,而后再实例化子类对象,调用子类的构造方法。而这个时候,对于子类的构造而言,就相当于隐含了一个super()的形式.
!!!super调用父类构造时,一定要放在构造方法的首行上。
继承-子父类中成员变量的特点
当子父类中出现了同名成员变量时,在子类中若要访问父类中的成员变量,必须使用关键字 super
来完成。super 用来表示当前对象中包含的父类对象空间的引用
在子类中,访问父类中的成员变量格式:
super.父类中的成员变量
继承-子父类中成员方法特点-重写&应用
①子父类中成员方法的特点
当在程序中通过对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
看如下代码:
class Fu{
public void show(){
System.out.println("Fu 类中的 show 方法执行");
}
}
继承
class Zi extends Fu{
public void show2(){
System.out.println("Zi 类中的 show2 方法执行");
}
}
测试
public class Test{
public static void main(String[] args) {
Zi z = new Zi();
z.show(); //**子类中没有 show 方法,但是可以找到父类方法去执行**
z.show2();
}
}
成员方法特殊情况——覆盖
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为 override 重写、复写或者覆盖。
举例:比如手机,当描述一个手机时,它具有发短信,打电话,显示来电号码功能,后期由于手机
需要在来电显示功能中增加显示姓名和头像,这时可以重新定义一个类描述智能手机,并继承原有描述
手机的类。并在新定义的类中覆盖来电显示功能,在其中增加显示姓名和头像功能。
//手机类
class Phone{
public void sendMessage(){
System.out.println("发短信");
}
public void call(){
System.out.println("打电话");
}
public void showNum(){
System.out.println("来电显示号码");
}
}
//智能手机类
class NewPhone extends Phone{
//覆盖父类的来电显示号码功能,并增加自己的显示姓名和图片功能
public void showNum(){
//调用父类已经存在的功能使用 super
super.showNum();
//增加自己特有显示姓名和图片功能
System.out.println("显示来电姓名");
System.out.println("显示头像");
}
}
重写需要注意的细节问题:
①子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
② 写法上稍微注意:必须一模一样:方法的返回值类型 方法名 参数列表都要一样。