JavaSE 面向对象OOP(上)
一、面向对象概述
1 面向过程&面向对象区别
-
面向过程
- 第一步做什么,第二步做什么…
- 面向过程适合处理一些简单的问题。
-
面向对象
- 分类的思维模式,首先分类,随后逐个解决分类下的细节。
- 面向对象适合处理负责的问题,适合多人协作的问题。
- 以类的方式组织代码,以对象组织封装数据
-
面向对象三大特性:封装、继承、多态
2 方法回顾+补充
- 方法的定义
- 修饰符
- 返回类型
- break: 跳出循环或switch, return:结束方法
- 方法名:注意命名规范 见名知意
- 参数列表:(参数类型,参数名) …
- 异常抛出: 随后填坑。
- 方法的调用
- 静态方法
- 非静态方法
- 实参、形参
- 值传递(Java)和引用传递 可查看我之前的blog,点击查看详情
- this关键字
静态方法和非静态方法调用的补充案例:
package com.oop.demo01;
//该类内含静态方法与非静态方法
public class Student {
//static 修饰的方法和类一起加载的
//而非静态方法是在类实例化之后生成
//静态方法
public static void say(){
System.out.println("Say!");
}
//非静态方法
public void write(){
System.out.println("Write!");
}
}
package com.oop.demo01;
//该类为测试类
public class Demo02 {
public static void main(String[] args) {
//静态方法 static
//调用方法:类名.方法名;
Student.say(); //Say!
//非静态方法 没有static
//调用方法:对象类型 对象名 = new 对象类名; 使用实例对象操作方法;
Student st = new Student();
st.write();//Write!
}
}
注意两种方法各自的调用方式!
3 类和对象
- 类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但是并不能代表某个具体的事物。
- 对象是类的实例。
- 也可理解为:类是一个模版:抽象; 对象是一个具体的实例。
创建类和对象的案例:
package com.oop.demo02;
//学生类 (属性+方法)
public class Student {
//属性:字段/成员变量
String name;//null
int age; //0
//方法:
public void study(){
System.out.println(this.name+" is studying");
}
public void nostudy(){ System.out.println(this.name+" is not studing");}
}
package com.oop.demo02;
//测试类:一个项目应该只有一个main方法
public class Application {
public static void main(String[] args) {
//类:抽象的,实例话
//类实例化后会返回一个自己的对象
//对象就是一个Student类的具体实例
Student j = new Student();
Student d = new Student();
j.name = "Jever";
j.age = 19;
d.name = "Demut";
d.age = 23;
System.out.println(j.name);
j.study();
System.out.println(d.name);
d.nostudy();
}
}
//运行结果:
/*
运行结果:
Jever
Jever is studying
Demut
Demut is not studing
*/
4 创建对象 <-构造器->
-
构造器:
- 和类名相同
- 没有返回值
-
作用:
- new 本质是在调用构造器
- 初始化对象的值
-
注意:
- 定义了有参构造之后,如果想使用无参构造,需要显示的定义一个无参的构造器。
-
构造器案例:
package com.oop.demo02; //Person类(此类仅包含属性与构造器) public class Person { String name; int age; //实例化初始值 //无参构造器 public Person(){ } //有参构造器 public Person(String name, int age){ this.name = name; this.age = age; } }
package com.oop.demo02; //测试类 public class Application2 { public static void main(String[] args) { //使用有参量的构造器 Person person = new Person("Jever",19); System.out.println(person.name); //Jever System.out.println(person.age); //19 } }
5 创建对象内存分析
- 代码如下:
package com.oop.demo03;
//Pet类 (属性+方法)
public class Pet {
String name;
int age;
//无参构造会自动生成
public void shout(){
System.out.println("Shouting!");
}
public static void eat(){
System.out.println("Eating");
}
}
package com.oop.demo03;
//测试类 生成两实例对象,并进行操作
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "旺财";
dog.age = 3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet cat = new Pet();
Pet.eat();
}
}
- 该过程示意图如下:
二、面向对象三大特性
1 封装
-
该露的露,该藏的藏
- 程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合指仅仅暴露少量的方法给外部使用。
-
封装值数据的隐藏
- 通常应禁止直接方位一个对象中数据的实际表示,而是应通过操作接口来访问,这称为封装。
-
属性私有,get/set(可在set中进行安全性的判断)
-
封装的作用:
- 提高程序安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 增加系统可维护性
案例展示:
package com.oop.demo04;
//属性私有,get/set
public class Student {
//以下属性私有,数据被封装
private String name; //姓名
private int id; //学号
private char gender; //性别
private int age; //年龄 注意不可无限增长
//提供一些可以操作私有属性的方法!
//提供public 的get、set方法
//get 获得这个数据
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
//set 给私有数据设置值
public void setName(String name){
this.name = name;
}
public void setAge(int age){//进行安全性判断
if (age>110 || age<0){//不合法
this.age = 0;
}else {
this.age = age;
}
}
}
package com.oop.demo04;
//测试类
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("Jever");
System.out.println(s1.getName());
s1.setAge(999);
System.out.println(s1.getAge());
}
}
2 继承
2.1 继承基础
- 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
- 使用关键字extends(扩展)。子类是父类的扩展。
- Java中类只有单继承,没有多继承。
- 所有类默认继承object类。
继承案例:
package com.oop.demo05;
//Person类:父类
public class Person {
//public
//protected
//default
//private
private String name; //子类无法继承
public void say(){
System.out.println("I am saying!");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
package com.oop.demo05;
//学生类
public class Student extends Person{}
package com.oop.demo05;
//测试类
public class Application {
public static void main(String[] args) {
Student st = new Student();
st.say();
}
}
注意访问时方法权限的问题!
2.2 super详解
注意:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中!
- super和this不能同时调用构造方法!
VS this:
-
代表对象不同:
- this: 调用本类对象;
- super: 代表父类对象应用
-
前提:
- this:没有继承时也可以使用;
- super:只能在继承条件下才可以使用。
-
构造方法:
- this():本类的构造;
- super(): 父类的构造。
案例展示:
package com.oop.demo05;
//在Java中,所有的类都默认继承Object类。
//Person类:父类
public class Person {
public Person(){
System.out.println("Person无参构造器!");
}
protected String name = "Demut";
public void print(){
System.out.println("Person");
}
}
package com.oop.demo05;
//学生类
public class Student extends Person{
public Student(){
//此处隐藏了super();
//调用了父类的无参构造器,且调用父类的构造器语句必须在子类的第一行。
super();
System.out.println("Student无参构造器!");
}
private String name = "Jever";
public void print(){
System.out.println("Student");
}
public void test1(){
System.out.println(this.name);//使用this访问本类中name Jever
System.out.println(super.name);//使用super访问父类中name Demut
}
public void test2(){
this.print(); //使用this访问本类中方法 Student
super.print(); //使用super访问父类中的方法 Person
}
}
package com.oop.demo05;
//测试类
public class Application {
public static void main(String[] args) {
Student s = new Student();
s.test1();
s.test2();
}
}
/*
测试结果:
Person无参构造器!
Student无参构造器!
Jever
Demut
Student
Person
*/
2.3 方法重写
(父类的功能,子类不一定需要,或者不一定满足!故需要重写)
重点:需要有继承关系,子类重写父类的方法!
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小: public -> protected -> default -> private
- 抛出异常:范围可以被缩小但不能扩大。(破洞只能越填越小)
重写中子类的方法和父类方法头一致;方法体不同!
-
案例展示:
package com.oop.demo05; //父类:A public class A { public static void test(){ System.out.println("A=>test()"); } public void test2(){ System.out.println("A=>test2()"); } }
package com.oop.demo05; //子类:B public class B extends A{ public static void test(){ System.out.println("B=>test()"); } @Override//重写 public void test2() { System.out.println("B=>test2()"); } }
package com.oop.demo05; //测试类 public class Application2 { //静态方法和非静态方法的区别很大!!! //重写与静态方法无关,只与非静态有关! public static void main(String[] args) { //方法的调用只和左边定义的数据类型有关。 B b = new B(); b.test(); //B=>test() //父类的引用指向了子类 A a = new B(); a.test(); //A=>test() b.test2(); //B=>test2() a.test2(); //B=>test2() } }
写在最后
热爱可抵岁月漫长!
To Demut and Dottie!