java的核心思想就是OOP,面向对象编程。
面向对象
面向对象编程:OOP (Object-Oriented Programming)
面向对象的本质就是: 以类的方式组织代码,以对象的方式封装数据。
对象,是具体的事物。类,是抽象的,是对对象的抽象。
抽象
三大特性:
- 封装
- 继承
- 多态
从认识论角度考虑:是现有对象后又类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
从代码运行角度考虑:是先有类后有对象。类是对象的模版。
方法的调用
静态方法,直接可以用类名.静态方法名 调起来。
非静态方法,不能直接用类名调用起来。需要new一个类,然后用类的实例.方法名 调起来。
Student.java
public class Student.java
{
//静态方法
public static void say() {
System.out.println("学生说话了!");
}
//非静态方法
public void say2() {
System.out.println("学生说话了!");
}
}
Demo01.java
//Demo01 类
public class Demo01 {
//main 方法
public static void main(String[] args) {
// Student.say();
//实例化这个类 new
Student student = new Student();
student.say2();
}
}
静态方法和非静态方法的创建时期:
package com.mysoft.oop;
public class Demo02 {
public static void main(String[] args) {
}
//static 和类一起加载的 (创建的早)
public static void a() {
//b();
}
//类实例化之后才存在。
public void b() {
}
}
形参和实参
package com.mysoft.oop;
public class Demo03 {
public static void main(String[] args) {
// 实际参数和形式参数的类型要对应!
int sum = add(1, 5);
System.out.println(sum);
}
public static int add(int a, int b) {
return a + b;
}
}
值传递和引用传递
java里都是值传递!
package com.mysoft.oop;
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);//1
Demo04.change(a);
System.out.println(a);//1
}
//返回值为空
public static void change(int a) {
a = 10;
}
}
一个类里面,可以定义多个class。但是只能有一个是public。
引用传递。(使用对象的传递)
package com.mysoft.oop;
public class Demo05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//null
change(person);
System.out.println(person.name);//tom
}
public static void change(Person person) {
//person是一个对象:指向的是Person person = new Person(); 这是一个具体的人,可以改变属性
person.name = "tom";
}
}
//定义了一个Person类,有一个属性:name
class Person {
String name;//null
}
创建与初始化对象
- 使用new关键字创建对象。
- 使用new关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化
以及对类中构造器的调用。 - 类中的构造器也称为构造方法,是在创建对象的时候必须调用的。有以下两个特点:
1.必须和类的名字相同
2.必须没有返回类型,也不能写void。
一个项目应该只存在一个main方法。
Application.java
package com.mysoft.oop.demo02;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//类:抽象的,实例化
//类实例化后会返回一个自己的对象!
//student对象就是一个Student类的具体实例
Student xiaoMing = new Student();
Student xiaoLing = new Student();
xiaoMing.name = "xiaoming";
xiaoMing.age = 3;
System.out.println(xiaoMing.name);
System.out.println(xiaoMing.age);
xiaoMing.study();
System.out.println("=====================");
System.out.println(xiaoLing.name);
System.out.println(xiaoLing.age);
xiaoLing.study();
}
}
Student.java
package com.mysoft.oop.demo02;
//学生类
public class Student {
//属性:字段
String name;//null
int age; //0
//方法
public void study() {
System.out.println(this.name + "在学习!");
}
}
1.使用new关键字,本质是在调用构造器
2.有参构造:一旦定义了有参构造,无参就必须显式定义
Alt + insert 生成构造器,可以选择几个参数 做成构造方法。
this. =
this代表的是当前类,后面是传进来的值。
package com.mysoft.oop.demo02;
public class Person {
//一个类即使什么都不写,它也会存在一个方法
String name;
//显示的定义构造器
//实例化初始值
//1.使用new关键字,本质是在调用构造器
public Person() {
this.name = "duola";
}
//有参构造:一旦定义了有参构造,无参就必须显式定义
public Person(String name) {
this.name = name;
}
}
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//new 实例化了一个对象
// Person person = new Person();
Person person = new Person("Ameng");
System.out.println(person.name);//Ameng
}
}
创建对象内存分析
Pet.java
package com.mysoft.oop.Demo03;
public class Pet {
String name;
int age;
public void shout() {
System.out.println("叫了一声");
}
}
Application.java
package com.mysoft.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();
}
}
生成的对象都是放在堆栈里。
具体大概图如下:
封装
封装:
该露的露,该藏的藏
我们程序设计要最求:高内聚,低耦合。
高内聚:类的内部数据操作细节自己完成,不允许外部干涉。
低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏):应禁止直接访问一个对象中的数据,而应通过操作接口来访问,这称为信息隐藏。
记住这句话就够了:属性私有,get/set
package com.mysoft.oop.demo04;
//类 private:私有
public class Student {
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;//年龄
//提供一些可以操作这个属性的方法!
//提供一些public的set,get方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 120 || age < 0) {//不合法的
this.age = 3;
} else {
this.age = age;
}
}
}
package com.mysoft.oop.demo04;
/*
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护增加了
*/
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("朵拉");
System.out.println(s1.getName());
s1.setAge(999);//不合法的
System.out.println(s1.getAge());
}
}
继承
-
extends的意思是“扩展”。子类是对父类的扩展。
-
java中类只有单继承,没有多继承!
-
object类
-
super
-
方法重写
在java中,所有的类,都默认直接或者间接继承Object
super - this
一个代表父类,一个代表当前的
私有的东西,无法被继承!
Person.java
package com.mysoft.oop.demo05;
//在java中,所有的类,都默认直接或者间接继承object
//Persono 人: 父类
public class Person {
public Person() {
System.out.println("Person无参执行了");
}
protected String name = "duola";
}
Student.java
package com.mysoft.oop.demo05;
public class Student extends Person {
private String name = "dafengqi";
public Student() {
//隐藏代码:调用了父类的无参构造
super();//调用父类的构造器,必须要在子类构造器的第一行
System.out.println("Student无参执行了");
}
public void test(String name) {
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
调用:
Application.java
package com.mysoft.oop.demo05;
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.test("tom");
}
}
输出结果:
Person无参执行了
Student无参执行了
tom
dafengqi
duola
方法的重写 Override 重点--->多态
重写都是方法的重写,和属性无关。
静态方法和非静态方法的调用有区别
静态方法:方法的调用只和左边,定义的数据类型有关
非静态:重写
父类:
B.java
package com.mysoft.oop.demo05;
//重写都是方法的重写,和属性无关
public class B {
public void test() {
System.out.println("B=>test()");
}
}
子类:
A.java
package com.mysoft.oop.demo05;
//继承
public class A extends B {
//Override 重写
@Override //注解:有功能的注释!
public void test() {
//super.test();
System.out.println("A=>test()");
}
}
package com.mysoft.oop.demo05;
public class Application {
public static void main(String[] args) {
//静态方法和非静态方法区别很大!
//静态方法: 方法的调用只和左边,定义的数据类型有关
//非静态: 重写
A a = new A();
a.test(); //A=>test()
//父类的引用指向了子类
B b = new A();
b.test(); //A=>test()
}
}
多态
多态:
即,同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
注意:多态是方法的多态,属性没有多态性。
一个对象的实际类型是确定的
可以指向的应用类型就不确定了:父类的引用指向子类。
Person.java
package com.mysoft.oop.demo06;
public class Person {
public void run() {
System.out.println("father");
}
}
Student.java
package com.mysoft.oop.demo06;
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat() {
System.out.println("eat");
}
}
Application.java
package com.mysoft.oop.demo06;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了:父类的引用指向子类
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
s1.eat();//eat
//s2.eat(); //语法error,因为Person没有eat方法
((Student) s2).eat(); //eat 转型成Student之后,才可以执行Student特有的方法
s1.run(); //son
s2.run(); //son 子类重写了父类的方法,执行子类的方法
}
}
/*
多态注意事项:
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系 类型转换异常!(ClassCastException)
3.存在条件:继承关系,方法需要重写, 父类引用指向子类对象! Father f1 = new Son();
下记的这些无法重写:
1.static方法, 属于类,它不属于实例
2.final 常量
3.private 方法
*/
类型转换:
子类转换为父类,可能丢失自己的本来的一些方法。
package com.mysoft.oop.demo06;
public class Application {
public static void main(String[] args) {
//类型之间的转换: 父 子
//子类转换为父类,可能丢失自己的本来的一些方法!
Student student = new Student();
student.eat();
Person person = student;
person. //本例,只剩run方法了,eat方法看不到了
}
}