Java面向对象
1. 什么是面向对象?
Java的核心思想就是OOP(面向对象编程)
2. 方法的定义和方法的调用
1. 方法的定义
代码示例
package com.baidu.www;
import java.io.IOException;
import java.util.Arrays;
public class test {
// main方法
public static void main(String[] args) {
}
public String sayHello()
{
return "Hello, World!";
}
public void Hello()
{
return;
}
public int max(int a, int b)
{
// 三元运算符
return a > b ? a : b;
}
// 数组下标越界 Arrayindexoutofbounds
public void readFile(String file) throws IOException{
}
}
2. 方法的调用
代码示例
(1)Student.java
package com.baidu.www;
public class student {
// 静态方法
public static void fun1() {
System.out.println("静态方法。");
}
// 非静态方法
public void fun2() {
System.out.println("非静态方法。");
}
}
(2)test.java
package com.baidu.www;
public class test {
public static void main(String[] args) {
// 静态方法
student.fun1();
// 非静态方法
student stu = new student();
stu.fun2();
// 值传递
int a = 1;
System.out.println(a);
change(a);
System.out.println(a);
// 引用传递
Person person = new Person();
change1(person);
System.out.println(person.name);
}
// 值传递
public static void change(int a)
{
a = 10;
System.out.println(a);
}
// 引用传递
public static void change1(Person person){
person.name = "刷刷";
}
}
class Person{
String name; // null
}
3. 构造器
!!!Alt + Insert 快捷键生成构造器
(1)构造器:和类名相同、没有返回值
(2)作用:new本质是在调用构造方法、初始化对象的值
(3)注意点:定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
代码示例
package com.baidu.www;
public class Person {
String name;
// // 使用new关键字,本质是在调用构造器
// public Person() {}
//
// // 有参构造
// // 一旦定义了有参构造,无参就必须显式定义
// public Person(String name)
// {
// this.name = name;
// }
// Alt + insert生成构造器
public Person() {
}
public Person(String name) {
this.name = name;
}
}
4. 创建对象内存分析
5. 封装(高内聚,低耦合)
属性私有:get / set 方法 ---> Alt + Insert 快捷键生成 get、set 方法
代码示例
(1)Student.java
package com.baidu.www;
public class Student {
private String name;
private int id;
private char sex;
private int age;
// 提供一些操作这个属性的方法
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age) {
if(age > 120 || age < 0) this.age = 3;
else this.age = age;
}
public int getAge() {
return age;
}
}
(2)test.java
package com.baidu.www;
public class test {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("刷刷");
System.out.println(s1.getName());
s1.setAge(130);
System.out.println(s1.getAge());
s1.setAge(12);
System.out.println(s1.getAge());
}
}
6.继承 extends
Java只有单继承,没有多继承。
(1)Object类:Java中,所有的类,都默认直接或间接继承Object
(2)super
代码示例
(1)Person类
package com.baidu.www;
public class Person {
// Java中,所有的类,都默认直接或间接继承Object
protected String name = "父类";
public Person() {
System.out.println("父类的无参构造。");
}
}
(2)Student类
package com.baidu.www;
public class Student extends Person{
private String name = "子类";
public Student() {
// 隐藏代码 super();
System.out.println("子类的无参构造。");
}
public void test(String name)
{
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
(3)test类
package com.baidu.www;
public class test {
public static void main(String[] args) {
Student stu = new Student();
stu.test("洛洛");
}
}
注意点
- super 调用父类的构造方法,必须在构造方法第一行
- super 必须只能出现在子类的方法或者构造方法中
- super 和 this 不能同时调用构造方法
Super 和 this
- 代表的对象不同
(1)this:本身调用者这个对象
(2)super:代表父类对象的应用
- 前提
(1)this:没有继承也可以使用
(2)super:只能在继承条件才能使用
- 构造方法
(1)this():本类的构造
(2)super():父类的构造
(3)方法重写
代码示例
(1)B类
package com.baidu.www;
public class B {
public void test()
{
System.out.println("B。");
}
}
(2)A类
package com.baidu.www;
public class A extends B{
// 注解:有功能的注释。
@Override
public void test() {
System.out.println("A。");
}
}
(3)test类
package com.baidu.www;
public class test {
// 静态方法和非静态方法有区别
public static void main(String[] args) {
// 静态方法:方法的调用只和左边定义的数据类型有关。
// 非静态方法:重写,public方式
A a = new A();
a.test(); // A
// 父类的引用指向子类
B b = new A();
b.test(); // B A
}
}
重写:需要有继承关系。
(1)方法名必须相同
(2)参数列表必须相同
(3)修饰符:范围可以扩大
(4)抛出的异常:范围可以被缩小,但不能扩大。
为什么重写:
- 父类的功能,子类不一定需要,或者不一定满足。
7. 多态
代码示例
(1)Person类
package com.baidu.www;
public class Person {
public void run(){
System.out.println("父类的方法。");
}
}
(2)Student类
package com.baidu.www;
public class Student extends Person{
@Override
public void run() {
System.out.println("子类的方法。");
}
public void eat(){
System.out.println("子类自己的方法。");
}
}
(3)test类
package com.baidu.www;
/**
* 多态注意事项:
* 1. 多态是方法的多态,属性没有多态。
* 2. 父类和子类,有联系才能转换,否则发生类型转换异常 ClassCastException
* 3. 存在关系:继承关系,方法需要重写,父类引用指向子类对象 father f1 = new Son();
*
* 没有多态:
* 1. static 方法,属于类,它不属于实例
* 2. final 常量
* 3. private方法
*/
public class test {
public static void main(String[] args) {
// 一个对象的实际类型是确定的。
// 可以指向的引用类型是不确定的。
// Student 能调用的方法都是自己的或者继承父类的。
Student s1 = new Student();
// 父类的引用指向子类
// 父类型,可以指向子类,但是不能调用子类独有的方法。
Person s2 = new Student();
Object s3 = new Student();
s1.run();
s2.run(); // 子类重写了父类的方法,执行子类的方法。
s1.eat();
((Student) s2).eat(); // 强制转换
}
}
8. instanceof和类型转换
(1)instanceof
代码示例
(1)Person类
package com.baidu.www;
public class Person {
}
(2)Student类
package com.baidu.www;
public class Student extends Person{
}
(3)Teacher类
package com.baidu.www;
public class Teacher extends Person{
}
(4)test类
package com.baidu.www;
public class test {
public static void main(String[] args) {
// x instanceof y 父子类可以编译通过
// x所指向的实际类型有关系也可以编译通过
// Object > String
// Object > Person > Teacher
// Object > Person > Student
Object object = new Student();
System.out.println(object instanceof Object);
System.out.println(object instanceof Person);
System.out.println(object instanceof Student);
System.out.println(object instanceof Teacher);
System.out.println(object instanceof String);
System.out.println("=================================");
Person person = new Student();
System.out.println(person instanceof Object);
System.out.println(person instanceof Person);
System.out.println(person instanceof Student);
System.out.println(person instanceof Teacher);
// System.out.println(person instanceof String); // 同级,编译报错
System.out.println("=================================");
Student student = new Student();
System.out.println(student instanceof Object);
System.out.println(student instanceof Person);
System.out.println(student instanceof Student);
// System.out.println(student instanceof Teacher); // 编译报错
// System.out.println(student instanceof String); // 编译报错
}
}
(2)类型转换
代码示例
(1)Person类
package com.baidu.www;
public class Person {
}
(2)Student类
package com.baidu.www;
public class Student extends Person{
public void go(){
System.out.println("Gogogo!");
}
}
(3)test类
package com.baidu.www;
public class test {
public static void main(String[] args) {
/**
* 1. 父类引用指向子类的对象
* 2. 子类转换为父类。向上转型:不用强制转换
* 3. 父类转换为子类,向下转型:强制转换
* 4. 方便方法的调用,减少重复的代码。
*/
// 子类 转化 父类 不需要类型转换
// 子类转化为父类可能丢失本身的一些方法
Person person = new Student();
// 父类 转化 子类 需要类型转换
// Student student = (Student)person;
((Student)person).go();
}
}
9. static关键字
(1)static静态变量和方法
代码示例
package com.baidu.www;
public class Student{
private static int age; // 静态变量
private double score; // 非静态变量
/**
* 非静态方法可以调用静态方法
* 静态方法可以调用静态方法
* 静态方法不可以调用非静态方法
*/
public void run(){
go();
}
public static void go(){
System.out.println("Gogogo!");
}
public static void main(String[] args) {
Student student = new Student();
System.out.println("=============================");
System.out.println(Student.age);
System.out.println(student.age);
System.out.println(student.score);
new Student().run();
Student.go();
go();
}
}
(2)static与匿名代码块
代码示例
package com.baidu.www;
public class Student{
// 1.
static {
// 静态代码块(匿名代码块)
System.out.println("静态的匿名代码块。");
}
// 2.
{
// 代码块(匿名代码块)
System.out.println("匿名代码块。");
}
// 3.
public Student() {
System.out.println("构造器。");
}
public static void main(String[] args) {
new Student();
System.out.println("==================================");
new Student();
}
}
结果
静态的匿名代码块。
匿名代码块。
构造器。
==================================
匿名代码块。
构造器。
(3)static静态导入包
代码示例
package com.baidu.www;
// 静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Student{
public static void main(String[] args) {
System.out.println(random());
System.out.println(PI);
}
}
10. final关键字
final 修饰类,不能被继承
(1)概述
(2)注意事项
代码示例
package com.baidu.www;
public class A {
public static void main(String[] args) {
}
}
class AA{
public final double CONST = 0.00;
public final double CONST1;
public final double CONST2;
public AA() {
this.CONST1 = 0.00;
}
{
CONST2 = 0.00;
}
// 静态常量
public static final double CONST3 = 0.00;
public static final double CONST4;
static{
CONST4 = 0.00;
}
}
代码示例
package com.baidu.www;
public class BB {
public static void main(String[] args) {
System.out.println(BBB.num);
}
}
class BBB{
// public static int num = 10000;
/**
* 不会导致类加载!!!
*/
public final static int num = 10000;
static {
System.out.println("静态代码块执行。");
}
}
11. 抽象类 abstract
代码示例
(1)Action类
package com.baidu.www;
// Abstract 抽象类。
public abstract class Action {
// abstract 抽象方法,只有方法名字,没有方法的实现。
// 抽象方法必须在抽象类中
// 不能 new 抽象类,只能靠子类实现。
public abstract void doSomething();
// 抽象类中可以写普通的方法
public void hello(){
System.out.println("Hello!");
}
}
(2)A类
package com.baidu.www;
// 抽象类的所有方法,继承了它的子类,必须要实现他的方法
// 除非子类也是抽象类
public class A extends Action{
@Override
public void doSomething() {
}
}
12. 接口的定义与实现
代码示例
(1)TimeService类
package com.baidu.www;
public interface TimeService {
void timer();
}
(2)UserService类
package com.baidu.www;
// interface 定义的关键字
// 接口都需要有实现类
public interface UserService {
// 属性:常量
public static final int AGE = 90;
int AG = 90;
// 接口中的所有定义其实都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void quert(String name);
}
(3)UserServiceImpl类
package com.baidu.www;
/**
* 接口的作用:
* 1. 约束
* 2. 定义方法,不同的实现
* 3. public abstract 方法
* 4. public abstract final 常量
* 5. 接口不能被实例化,接口中没有构造方法
* 6. implements可以实现多个接口
* 7. 必须要重写接口中的方法
*/
// 抽象类:extends
// 类 可以实现接口 implements 接口
// 实现接口的类,就需要重写接口中的方法
// 从接口实现多继承
public class UserServiceImpl implements UserService, TimeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void quert(String name) {
}
@Override
public void timer() {
}
}
函数式接口:只有一个方法的接口
代码示例
(1)MyInterface类
package com.baidu.www;
public interface MyInterface {
public abstract void say();
}
(2)Test类
package com.baidu.www;
public class Test {
public static void main(String[] args) {
// MyInterface mi = new MyInterface() {
// @Override
// public void say() {
// System.out.println("嘻嘻");
// }
// };
// mi.say();
MyInterface myInterface = ()->{
System.out.println("嘻嘻。");
};
myInterface.say();
}
}
13. N种内部类
1. 成员内部类
代码示例
(1)outer.java
package com.baidu.www;
// 成员内部类
public class Outer {
private int id = 29;
public void out(){
System.out.println("这是外部类的方法。");
}
class Inner {
public void in() {
System.out.println("这是内部类的方法。");
}
// 获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
}
(2)test.java
package com.baidu.www;
// 一个JAVA类可以有多个class类,但是只能有一个public class类
public class test {
public static void main(String[] args) {
Outer outer = new Outer();
// 通过外部类实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
}
2. 其它
代码示例
(1)Outer类
package com.baidu.www;
public class Outer {
private int n1 = 10;
private static int n2 = 20;
// 局部内部类
public void method(){
class Inner{
public void in(){
}
}
}
// 静态内部类
/**
* 放在成员位置
* 使用static修饰
* 可以直接访问外部类的所有静态成员,但不能访问非静态成员
*/
static class Inner2{
public void say(){
System.out.println(n2); //
}
}
}
(2)test类
package com.baidu.www;
public class test {
public static void main(String[] args) {
// 匿名内部类
// 没有名字初始化类
// 不用将实例保存到变量中
new Outer();
new UserService(){
@Override
public void Go() {
System.out.println("A");
}
};
}
}
interface UserService{
void Go();
}
14. 枚举类
(1)自定义枚举类
(2)enum枚举类
代码示例
package com.baidu.www;
public class en {
public static void main(String[] args) {
System.out.println(Season.SPRING);
System.out.println(Season0.SPRING);
}
}
class Season0{
private String name;
private String desc;
Season0(String name, String desc) {
this.name = name;
this.desc = desc;
}
public final static Season0 SPRING = new Season0("春天", "温暖");
public final static Season0 WINTER = new Season0("东天", "寒冷");
@Override
public String toString() {
return "Season0{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
enum Season{
SPRING("春天", "温暖"),WINTER("冬天","寒冷");
private String name;
private String desc;
Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
继承Enum类
Enum类常用方法
package com.baidu.www;
import java.util.Arrays;
public class en {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring.name());
// 输出枚举对象的次序(编号)
System.out.println(spring.ordinal());
// 反编译,返回定义的所有枚举对象数组
Season[] seasons = Season.values();
System.out.println(Arrays.toString(seasons));
// valueof 将字符串转换为枚举对象
Season winter = Season.valueOf("WINTER");
System.out.println(winter);
// 比较编号
/**
* public final int compareTo(E o) {
* Enum<?> other = (Enum<?>)o;
* Enum<E> self = this;
* if (self.getClass() != other.getClass() && // optimization
* self.getDeclaringClass() != other.getDeclaringClass())
* throw new ClassCastException();
* return self.ordinal - other.ordinal;
* }
*/
System.out.println(spring.compareTo(winter));
System.out.println(spring.compareTo(spring));
}
}
enum Season{
SPRING("春天", "温暖"),WINTER("冬天","寒冷");
private String name;
private String desc;
Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}