一、面向对象程序设计(Object Oriented Programming, OOP)
-
定义:
-
面向对象(Object Oriented,OO)是软件开发方法。
-
面向对象是一种对现实世界理解和抽象的方法。
-
-
作用:
-
系统结构较稳定
-
子系统相对独立
-
软件的可重用性、可维护性、可扩展性强
-
二、类和对象
1.类
-
程序中的类现实生活中的类别
-
是抽象的
-
具有相同属性和方法的一组对象的集合
-
类的定义:
//人类
public class Person {
//属性(成员变量):姓名 性别 年龄
String name;
char sex;
int age;
//方法(成员方法):吃 喝 自我介绍
public void eat(){
System.out.println("吃");
}
public void drink(){
System.out.println("喝");
}
public void ShowInfo(){
System.out.println("我叫:"+name+";我是"+sex+"生:我今年"+age+"岁");
}
}
2.对象
-
程序中的对象即现实生活中某类别下的特定个体 - 对象的创建和方法的调用
public static void main(String[] args) {
//创建对象
Person zhangSan = new Person();
//调用对象设置属性和方法
zhangSan.name = "张三";
zhangSan.age = 18;
zhangSan.sex = '男';
zhangSan.ShowInfo();
zhangSan.drink();
zhangSan.eat();
}
三、方法与方法重载
//带参方法的定义和调用
public class DaiChan {
public void Dai(String chan){
System.out.println(chan);
}
public static void main(String[] args) {
DaiChan daiChan = new DaiChan();
daiChan.Dai("测试参数");
}
}
-
注意事项
-
方法定义处的参数叫做形式参数(形参)
-
方法调用处传的值叫做实际参数(实参)
-
实参和形参数据类型要一致
-
-
方法传参
-
在以对象作为参数传递时,是传地址
-
在方法中改变值后,再拿到值也会发生改变
-
//修改小于60分的学生成绩
public void modifyStuScore(Student[] stus){
for (int i = 0; i < stus.length; i++) {
if (stus[i].score<60){
stus[i].score+=2;
}
}
}
public static void main(String[] args) {
ModifyScore m = new ModifyScore();
//定义了一个学生对象数组
Student s1 = new Student();
s1.name = "张三";
s1.score = 43;
Student s2 = new Student();
s2.name = "李四";
s2.score = 93;
Student s3 = new Student();
s3.name = "李四";
s3.score = 59;
Student[] stus = new Student[3];
stus[0] = s1;
stus[1] = s2;
stus[2] = s3;
//显示学生信息
m.showStus(stus);
m.modifyStuScore(stus);
m.showStus(stus);
}
//结果为
张三的成绩是43
李四的成绩是93
李四的成绩是59
张三的成绩是45
李四的成绩是93
李四的成绩是61
构造方法
//无参构造 系统默认提供这个写法
public Student(){}
//带参构造
public Student(String name,int score){
this.name = name;
this.score = score;
}
注意:
-
系统会自动创建无参构造方法
-
当定义了带参的构造方法时,无参的构造方法需要自己手动创建
方法重载
:同一个方法的参数不同
//简易计算器 实现方法的重载
public class Calc {
//加法 两个整数
public void add(int num1,int num2){
int sum = num1+num2;
System.out.println(num1+"+"+num2+"="+sum);
}
//加法 两个浮点数
public void add(double num1,double num2){
double sum = num1+num2;
System.out.println(num1+"+"+num2+"="+sum);
}
//加法 三个浮点数
public void add(double num1,double num2,double num3){
double sum = num1+num2+num3;
System.out.println(num1+"+"+num2+"+"+num3+"="+sum);
}
public static void main(String[] args) {
Calc calc = new Calc();
calc.add(1,2);
calc.add(1.0,2.0);
calc.add(1.0,2.0,3.0);
}
}
成员变量和局部变量
-
作用域不同
-
局部变量的作用域仅限于定义他的方法
-
成员变量的作用域在整个类内部都是可见的
-
-
初始值不同
-
Java会给成员变量一个初始值
-
Java不会给局部变量赋予初始值
-
-
注意
-
在同一个方法中,不允许有同名局部变量
-
在不同的方法中,可以同名局部变量
-
在一个类中,成员变量和局部变量同名时,局部变量具有更高的优先级
-
四、封装和继承
封装
实现:
-
修改属性的可见性:设置为private
-
创建公有的getter/setter方法(用于读写)
-
在getter/setter方法中加入属性控制语句
package page3;
//狗狗类
public class Dog {
private String name="无名氏";
private int health = 100;
private int love = 0;
private String strain = "拉布拉多";
//setter属性赋值
//getter属性取值
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
if (health<0||health>100){
System.out.println("宠物够的健康值只能在0-100");
this.health=60;
return;
}
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
if (love<0||love>100){
System.out.println("宠物够的亲密度只能在0-100之间");
this.love=60;
}
this.love = love;
}
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
}
包
-
包名由小写字母组成,不能以圆点开头或结尾
-
包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名
-
包名后续部分依不同机构内部的规范不同而不同
访问权限
修饰符 | 同一个类中 | 同一个包中 | 子类中 | 任何地方 |
---|---|---|---|---|
prvate | 可以 | 不可以 | 不可以 | 不可以 |
默认修饰符 | 可以 | 不可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
public | 可以 | 可以 | 可以 | 可以 |
Static
-
成员变量:静态变量,可以直接通过类名访问
-
成员方法:静态方法,可以直接通过类名访问
-
代码块:静态代码块,当Java虚拟机加载类是,就会执行该代码块
static变量
-
能被类的所有实例共享,可作为实例之间进行交流的数据
-
如果类的所有实例都包含一个相同的常量属性,可以定义为static
public class StaticTest {
static int num;
public static void main(String[] args) {
num++;
StaticTest test1 = new StaticTest();
test1.num++;
StaticTest test2 = new StaticTest();
test2.num++;
StaticTest test3 = new StaticTest();
test3.num++;
System.out.println(num);//4
}
}
stacic方法
-
静态方法:可以直接通过类名访问
-
静态方法中不能使用this和super
-
不能直接访问所属类的实例变量和实例方法
-
可直接访问类的静态变量和静态方法
-
-
实例方法:通过实例访问
-
可直接访问所属类的静态变量、静态方法、实例变量和实例方法
-
-
静态方法必须被实现
stacic代码块
-
jvm加载类时,加载静态代码块
-
如果有多个静态块,按顺序加载
-
每个静态代码块只被执行一次
public class StaticTest1 {
static int num=100;
static {
num+=100;
System.out.println(num);//200
}
static {
num+=100;
System.out.println(num);//300
}
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
StaticTest staticTest1 = new StaticTest();
System.out.println(StaticTest1.num);//300
}
}
继承
-
访问修饰符protected
-
可以修饰属性和方法
-
本类、同包、子类可以访问
-
-
子类可以继承父类
-
继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里
-
继承默认权限修饰符修饰的属性和方法,但子类和父类必须再同一个包里
-
-
子类不可以继承父类
-
private成员、构造方法、不在同包的父类中默认修饰符修饰的成员
-
方法重写和多态
- 成员变量:
- 调用成员变量,编译看左边,运行也看左边
- 编译看左边,javac编译代码的时候,会看左边的父类中有没有这个变量,如果又,编译成功,没有编译失败
- 运行也看左边,java运行代码的时候,实际获取的就是左边父类中成员变量的值
- 成员方法:
- 调用成员方法,编译看左边,运行看右边
- 编译看左边,javac编译代码的时候,会看左边的父类中有没有这个变量,如果又,编译成功,没有编译失败
- 运行看右边,java运行代码的时候,实际上运行的是子类中的方法
- 理解:
- Animal a = new Dog();
- 用a去调用变量和方法
- a是Animal类型的,所以默认都会去Animal这个类中去找
- 成员变量:在子类的对象中,会把父类的成员变量也继承下来
- 成员方法:如果子类对方法进行了重写,那么在虚方法表中会把父类的方法进行覆盖
//多态调用成员的特点
/**
*变量调用:编译看左边,运行也看左边
*方法调用:编译看左边,运行看右边
*/
public class demo1 {
public static void main(String[] args) {
Animal a = new Dog();
//调用成员变量,编译看左边,运行也看左边
//编译看左边,javac编译代码的时候,会看左边的父类中有没有这个变量,如果又,编译成功,没有编译失败
//运行也看左边,java运行代码的时候,实际获取的就是左边父类中成员变量的值
System.out.println(a.name);//动物
//调用成员方法,编译看左边,运行看右边
//编译看左边,javac编译代码的时候,会看左边的父类中有没有这个变量,如果又,编译成功,没有编译失败
//运行看右边,java运行代码的时候,实际上运行的是子类中的方法
a.show();
//理解:
//Animal a = new Dog();
//用a去调用变量和方法
//a是Animal类型的,所以默认都会去Animal这个类中去找
//成员变量:在子类的对象中,会把父类的成员变量也继承下来
//成员方法:如果子类对方法进行了重写,那么在虚方法表中会把父类的方法进行覆盖
}
}
class Animal{
String name = "动物";
public void show(){
System.out.println("Animal-----的show方法");
}
}
class Dog extends Animal{
String name = "狗";
public void show(){
System.out.println("Dog-----的show方法");
}
}
class Cat extends Animal{
String name = "猫";
public void show(){
System.out.println("Cat-----的show方法");
}
}
-
方法的重写或者方法的覆盖
-
子类根据需求对从父类继承的方法进行重新编写
-
重写时,可以用super.方法的方式来保留父类的方法
-
构造方法不能被重写
-
super
-
访问父类方法 super.print();
-
访问父类属性 super.name;
-
以上都要是非private
-
访问父类构造方法 1. super(); 2. super(name);
-
注意事项:
-
super代表的是父类对象
-
super只能出现在子类的方法和构造方法中
-
super调用构造方法时,只能是第一句
-
super不能访问父类的private成员
-
继承条件下构造方法的调用规则
-
子类构造方法没有通过super显示调用父类的有参构造方法,也没有通过this显示调用自身其他构造方法
-
系统默认调用父类的无参构造方法
-
子类构造方法通过super显示调用父类的有参构造方法
-
执行父类相应构造方法,而不执行父类无参构造方法
-
子类构造方法通过this显示调用自身的其他构造方法,在相应构造方法中应用以上两条规则
Object类
-
Object是一切类的父类
-
当一个类的参数为一个不确定的类时,可以使用object定义
主要方法
-
equals() 用于比较对象(引用对象)
-
hashCode() 用于取得Hash码
-
toString() 对象打印时调用