一,OOP 面向对象编程
类和对象的关系
类是一个具有相同属性和行为的对象的集合,只是其描述作用
对象是一个类的实际表现
清楚一个类有哪些内容?
public class 类名{
类中有哪些成员?
变量
方法:
修饰符:public private
返回值:
方法名:
参数列表:形式参数,实际参数
抛出异常:thorws
方法体
构造器,一般类中准备一个无参构造器和全参构造器
get/set方法
//描述一个类的字符串的形式
toString(); —> Object
}
构造器
又被称为构造方法:
public 类名(){
}
1.构造方法没有返回值,即省略返回值的声明
2.构造方法发名字必须时类名
3.构造方法的权限一般为public
4.构造方法一般用作成员变量的初始化
5.方法中方法体能写的内容,在构造方法中也可以去写,构造方法中也可以写逻辑,但是一般不推荐
6.构造方法也支持方法重载
7.构造方法也支持互相调用—>this
8.如果一个类中没有声明任何的构造器,则默认提供一个无参构造器来完成对象的创建.如果出现了任何一个构造器,则默认的构造器失效,如果需要无参的构造器,则需要手动声明
get/set方法以及构造器
先创建一个Teacher类
package com.buirp.day07;
public class Teacher {
private String name;
private int age;
private String gender;
double salary;
String desc = "哈哈哈";
//无参
public Teacher() {
this("bob");
System.out.println("这是无参构造器");
}
//单参name
public Teacher(String name) {
System.out.println("这是单参构造器");
this.name = name;
}
//全参
public Teacher(String name,int age,String gender,double salary) {
System.out.println("这是全参构造器");
this.name = name;
this.age = age;
this.gender = gender;
this.salary = salary;
addSalary(10000.0);
System.out.println(this.salary);
}
//加工资的方法
public void addSalary(double money) {
this.salary += money;
}
//gettter&setter
//设置名字
public void setName(String name) {
this.name = name;
}
//获得名字
public String getName() {
return this.name;
}
//设置年龄
public void setAge(int age) {
if(age>=0 && age <=200) {
this.age = age;
}else {
this.age = 0;
}
}
//获得年龄
public int getAge() {
return this.age;
}
//设置性别,字符类型
public void setGender(String gender) {
if("男".contentEquals(gender)) {
this.gender = "男";
}else if("女".contentEquals(gender)) {
this.gender = "女";
}else {
this.gender = "性别不详";
}
}
//设置性别,布尔类型
public void setGender(boolean gender) {
if(gender) {
this.gender = "男";
}else {
this.gender = "女";
}
}
//获得性别
public String getGender() {
return this.gender;
}
}
然后创建一个测试类:
package com.buirp.day07;
import java.util.Arrays;
import util.ArrayUtil;
//用来测试构造器
public class Test {
static boolean MALE = true;
static boolean FEMALE = false;
public static void main(String[] args) {
Teacher t1 = new Teacher();
//给t1的变量初始化
// t1.name = "tom";
// t1.age = 20;
// t1.gender = "男";
t1.setName("ff");
t1.setAge(2000);
t1.setGender("nonannonv");
t1.setGender(FEMALE);
t1.desc = "嘿嘿嘿";
//获得
System.out.println(t1.getName());
System.out.println(t1.getAge());
System.out.println(t1.getGender());
System.out.println(t1.desc);
Teacher t2 = new Teacher("huang");
Teacher t3 = new Teacher("hong", 22, "男", 30000.0);
//调用自定义的工具类来完成数组的排序
int[] array = new int[] {8,9,2,5,3,6,4};
array = ArrayUtil.sort(array, true);
System.out.println(Arrays.toString(array));
}
//测试一下方法重载
// public void add(int i) {}
// public void add(double d) {}
// public void add(int i,double d) {}
// public void add(int i,String s) {}
// public void add(double i,int d) {}
}
方法中的参数类型
实际参数:方法调用的时候传入的参数,有具体的值
形式参数:方法声明的时候传入的参数,仅作数据类型的占位,没有具体的值
方法中的参数传递
基本类型的参数传递:
在栈区复制了一份具体的值来参与方法的执行,值传递
引用类型的参数传递:
在栈区复制了一份指向堆区的地址参与方法执行,可能会影响原数据,地址传递(引用传递)
方法的调用
静态方法:
类名.方法名();//可以不通过new对象来实现
实例(对象)方法:
对象.方法名;//必须通过mew对象来实现
this关键字的使用方式
1.放在变量前面,用来区分同名的成员变量和参数
2.放在方法的前面,用来在本类中调用其他本类的方法(一般不用)
3.放在构造器前面,用来在一个构造器中调用其他的构造器
普通的方法调用:this.方法();
构造方法的调用:this(); //调用无参构造器
方法重载
1.发生在一个类中
2.方法名称一定是相同的
3.参数列表一定是不同的
参数的类型
参数的个数
参数的顺序
4.返回类型
5.抛出的异常
6.访问控制修饰符的权限
总结:必要条件123,456没有关系
创建对象的过程
Teacher t1 = new Teacher();
1.在栈区开辟空间保存引用
2.在堆区开辟空间保存实际的数据
3.把堆区的内存地址赋值给栈区的引用
4.给变量赋默认值(系统)
5.给变量显示的赋初始值
6.给代码块进行初始化
7.通过对应的构造器来完成对象的创建
二,面向对象的三(四)大特性
封装,继承,多态(抽象)
封装
1.数据隐藏
先让外部没有办法访问类的变量
使用private修饰变量
public private default protected
给成员变量提供统一访问的接口,实际上就是用方法来控制变量的赋值和访问—>get/set方法
get方法:有返回值,没有参数,返回值类型和变量的类型保持一致
set方法:有参数,没返回值,一般来讲,传入参数的类型和变量的数据类型保持一致
2.代码复用
一段代码如果写了两遍以上,后期可能还会再写,就会考虑封装方法
提供方法的输入和输出,以及方法的功能即可
继承
语法
public class Cat extends Animal
public class 子类 extends 父类
如果只写
public class Cat
等同于
public class Cat extends Object
规则
1.子类可以获得父类所提供的属性和方法,收到访问权限的控制
2.子类的构造器,默认先调用父类的空参构造器
3.如果子类想要在子类的构造器中调用父类的非空参构造器,需要现实的使用super来调用
super关键字
super代表当前类的父类的对象
super.变量 代表访问父类的变量值
super.方法名 代表调用父类的方法
super(); 代表调用父类的空参构造器
super和this一样,都必须放在构造器的第一行
super关键字和this关键字不能同时出现在同一个构造器中
方法重写
@override
该注解放在方法前面,可以检测该方法是否为重写方法
父类为大,子类为小
规则
1.发生在子父类关系当中
2.必须保证子父类中是相同的方法
所以在重写中不讨论方法的名字和参数列表
3.返回值
子类的返回值类型要小于父类的返回值类型,至少要相同
4.权限
子类的访问权限必须比父类的访问权限大,至少要相同
5.异常抛出
子类的抛出异常范围要小于父类的异常抛出,至少要相同
一同一大两小
封装的代码
以排序算法的封装为例
package util;
//自定义数组的一些工具类
public class ArrayUtil {
//排序算法的方法封装
public static int[] sort(int[] array,boolean flag) {
//判断一下是升序还是降序
if(flag) {
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++) {
if(array[j]>array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}else {
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++) {
if(array[j]<array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
return array;
}
}
继承以及方法重写等相关代码
例:
先创建一个动物类:
package com.buirp.day07;
public class Animal {
public String name;
public int legCount;
public String typeOfEat;
public Animal() {
this("动物",8,"杂食");
System.out.println("这是父类的空参构造器");
}
public Animal(String name,int legCount,String typrOfEat) {
this.name = name;
this.legCount = legCount;
this.typeOfEat = typrOfEat;
System.out.println("这是父类的全参构造器");
}
public void run() {
System.out.println(name+"用"+legCount+"条腿跑");
}
public void eat() {
System.out.println(name+"吃"+typeOfEat);
}
public void say() {
System.out.println("哈哈哈");
}
}
然后创建一个子类,猫猫类,继承自动物类:
package com.buirp.day07;
public class Cat extends Animal{
public boolean catchMouse;
public Cat() {
System.out.println("这是子类的空参构造器");
}
public Cat(boolean catchMouse) {
//调用一下父类的全参构造器//不会再调用父类的空参
super("猫",4,"鱼");
this.catchMouse = catchMouse;
System.out.println("这是子类的单参构造器");
}
@Override
public void say() {
super.say();
super.run();
super.eat();
System.out.println("喵喵喵");
}
}
接下来再创建一个测试类来测试继承相关内容
package com.buirp.day07;
public class ExtendsTest {
public static void main(String[] args) {
// Animal animal = new Animal();//先打印调用的全参,再打印空参
Cat cat = new Cat(true);//打印时先默认用父类的空参构造器
// animal.run();
// cat.run();
// System.out.println(cat.legCount);
cat.say();
}
}
三,心得
因为从数组开始就有部分知识处于一知半解,所以周末这两天一直在回头研究那部分,并对前两天不懂的地方重新进行了标注,也算是比较透彻的理解了数组的相关内容,并且在前两天的博客中也修改了相关内容,这个周末虽然累,但是收获还是很丰富的,下周加油!