8 面向对象
面向对象编程的本质就是:以类的方法组织代码,以对象的组织(封装)数据。
8.1 方法的回顾
package com.oop.demo01;
// Demo01 类
public class Demo01 {
// main方法
public static void main(String[] args) {
int c = 10;
int d = 90;
System.out.println(max(c,d));
sayHello();
}
/*
修饰符 返回值类型 方法名(...){
// 方法体
return 放回值;
}
*/
// return 结束方法,返回一个结果!
public static String sayHello(){
return "Hello,world";
}
public static int max(int a,int b){
return a>b ? a : b; // 三元运算符;
}
}
如果没有返回值在方法中的话,结果就会如下这段代码所示:
package com.oop.demo01;
// 值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
// a 的值始终没有改变过都还是1
System.out.println(a); // 1
change(a);
System.out.println(a); // 1
}
// 返回值为空
public static void change(int a){
a = 10;
}
}
8.2 类与对象的创建、基础使用
关于类的创建就是直接在IDEA中的文件下直接创建类,就是点Java的文件,进行编译以后就是点class的文件。创造对象就是:对象类型 对象名 = 对象值。
我是这样理解的:
类就可以看做一个做蛋糕的模具,而对象就是按照这个模具所做出来的一个个蛋糕,蛋糕可以外表一样,但是名字可以不一样。比如都是用Student这个类来创建对象。却可以有:
Student S1 = new Student();
Student S2 = new Student();
Student S3 = new Student();........................等等
package com.oop.demo01;
public class Demo02 {
// 静态方法
// 非静态方法
public static void main(String[] args) {
//实例化这个类
// 对象类型 对象名 = 对象值
Student student = new Student();
student.say();
}
// 有static就是和类一起加载的
public static void a(){
//c(); -->这里的方法如果调用的话会直接报错。
/*
因为被static修饰过的方法是和类一起加载的,
而他所调用的这个方法没有被static修饰,所以在实例化之后才存在。
*/
}
// 类实例化之后才存在
public void c(){
}
}
可以在类里面再创建一个类,并且在里面的类里调用其他的类,如下面这段代码:
package com.oop.demo01;
// 引用传递:对象,本质还是值传递
public class Demo05 {
public static void main(String[] args) {
Perosn perosn = new Perosn();
System.out.println(perosn.name); // null
change(perosn); // 调用了方法change
System.out.println(perosn.name); // 周某
}
public static void change(Perosn perosn){
// perosn是一个类:指向的---> Perosn perosn = new Perosn();这是一个具体的人,可以改变属性
perosn.name = "周某";
}
}
//定义了一个Perosn类,有一个属性:name
class Perosn{
String name; //这里定义了一个name属性,返回值为默认的null
}
8.3 构造器
关于构造器:一个类即使什么都不行都会存在一个方法,这个方法是一个没有参数的方法,
当我们创建对象时所使用的new关键字本质上是在调用我们的构造器。
需要注意的是:我们可以定义有参数的构造器,如果定义了他,就需要再一次定义本身已经存在的无参构造器。
package com.oop.demo02;
// java ---> class
public class Person {
// 一个类及时什么都不写它也会存在一个方法
// 显示的定义构造器
String name;
// 实例化初始值
//1. 使用new关键字,本质是在调用构造器
//2. 用来初始化值
// 无参的构造器
public Person(){
this.name = "周某";
}
// 有参构造:一旦定义了有参构造,无参就必须显示定义
public Person(String name){
this.name = name;
}
}
/*
在可执行的类中的代码:
public class AppLication {
public static void main(String[] args) {
//new 实例化了一个对象
Person person = new Person("周鹭巡");
System.out.println(person.name); // 周某
}
}
构造器:
1. 和类名相同
2.没有返回值
作用:
1. new 本质在调用构造方法
2. 初始化对象的值
注意点:
定义有参构造之后,如果想使用无参构造,显示定义一个无参的构造
*/
8.4 封装
关于封装就是在类里面定义属性的时候使用修饰符private,在这个类里面可以定义一些可以操作这个属性的方法,这些方法需要特定的名称。
get元素名 :获得这个元素的值
set元素名 :设置这个元素的值
package com.oop.demo04;
public class Student {
// 属性私有
private String name;
private int id;
private String sex;
private int age;
// 提供一些可以操作这个属性的方法!
// 提供一些public的get、set方法!
// get 获得这个数据
public String getName(){
return this.name;
}
// set 给这个数据设置值
public void setName(String name){
this.name = name;
}
public int getId(){
return this.id;
}
public void setId(int id){
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 120 && age > 0){
this.age = age;
} else{
this.age = 20;
}
}
}
/*
在可执行类中的代码:
public static void main(String[] args) {
Student S1 = new Student();
S1.setName("周鹭巡");
S1.setAge(999);
S1.setId(35);
S1.setSex("男");
System.out.println(S1.getSex());
System.out.println(S1.getId());
System.out.println(S1.getName());
System.out.println(S1.getAge());
}
封装:
1. 提高了程序的安全性,保护数据
2. 隐藏代码的实现细节
3. 统一接口
4. 系统可维护增加了
*/
8.5 继承、Super
继承就是直接在类名后面跟上关键词extends与父类的名字,子类可以继承父类的所有方法。
Super就是在子类中调用父类中的属性或者父类中的方法。
直接在子类的构造器的代码第一行使用代码super();,就是调用父类的构造器。
Person父类:
package com.oop.demo05;
// 在Java中,所有的类,都默认直接或者间接继承Object
// Person 人:父类
public class Person /*extends Object*/ {
public Person() {
System.out.println("Person无参执行了");
}
private int money = 10_0000_0000;
public void say(){
System.out.println("说什么呢?");
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
protected String name = "zhoumou";
// 私有的东西无法被继承
public void print(){
System.out.println("Person");
}
}
Student子类:
package com.oop.demo05;
// 学生 is 人: 派生类,子类
// 子类继承了父类,就会拥有父类的全部方法!
public class Student extends Person {
// Ctrl + H
public Student() {
// 隐藏代码:调用了父类的无参构造
super();//调用父类的构造器,必须在子类构造器的第一行
System.out.println("Student无参构造执行了");
}
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
private String name = "zlx";
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
8.6 方法的重写
我是这么理解的,当创建对象时,类型为这个对象所属的父类时,他所调用的父类引用的方法是指向的子类,就好像儿子不听爸爸话了。
其实方法的重写就是调用方法是,方法的修饰符静态与非静态的区别。
你给别人弄成了静态的话,那么调用时遵循的就是创建对象时左边的数据类型了。
如果是非静态的话,子类就不听父类话了,就都是向子类的方法看齐,你是调用到的父类的方法,但是引用到的确实子类的方法。
可执行类:
public class AppLication{
public static void main(String[] args) {
//静态的方法与非静态的方法区别很大
// 方法的调用只和左边的数据类型有关
A a = new A();
a.test();
// 父类的引用指向了子类
B b = new A();
b.test();
}
}
A类:
package com.oop.demo05;
public class A extends B {
@Override // 注解:有功能的注释!
public void test() {
System.out.println("A=>test()");
}
}
B类:
package com.oop.demo05;
// 重写都是方法的重写与属性无关
public class B {
public void test(){
System.out.println("B=>test()");
}
}
执行后的结果就是: