Java基础语法(五)
面向对象定义
什么是面向对象:

面向对象的本质:

方法的定义和调用

类与对象的创建

示例代码:
package com.gavin.oop;
public class Student {
//属性值
String name;
int age;
//方法
public void study() {
System.out.println(this.name + "在学习");
}
}
package com.gavin.oop;
public class Application {
public static void main(String[] args) {
//实例化学生类
Student xiaoming = new Student();
Student xiaohong = new Student();
//给实例化出来的xiaoming对象赋值
xiaoming.name = "张三";
xiaoming.age = 23;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
System.out.println(xiaohong.name);
System.out.println(xiaohong.age);
}
}
执行结果:

面向对象的本质:

构造器详解

示例代码:
package com.gavin.oop;
public class Person {
String name;
int age;
//无参构造器
//创建对象使用new关键字,本质是调用构造器
//构造器用来初始化值
public Person() {
}
//有参构造器
//一旦定义了有参构造器,无参构造器也要定义
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
package com.gavin.oop;
public class Application2 {
public static void main(String[] args) {
//使用有参构造器给Person对象中的属性赋值
Person person = new Person("张三", 23);
System.out.println(person.name);
System.out.println(person.age);
}
}
执行结果:

创建对象内存分析

封装详解

示例代码:
package com.gavin.oop;
public class Person2 {
//属性值用private修饰,表示私有
private String name;
private int age;
//set方法用来设置属性的值
public void setName(String name) {
this.name = name;
}
//get方法用来获取属性的值
public String getName() {
return name;
}
//set方法中可以自己定义,用来校验传入的值是否合法
public void setAge(int age) {
if (age > 120 || age < 0) {
this.age = 3; //不合法
} else {
this.age = age; //合法
}
}
public int getAge() {
return age;
}
}
package com.gavin.oop;
public class Application3 {
public static void main(String[] args) {
Person2 person2 = new Person2();
person2.setName("张三");
//传入不合法的值
person2.setAge(123);
System.out.println(person2.getName());
System.out.println(person2.getAge());
}
}
执行结果:

封装的作用:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统的可维护增加了
继承

示例代码:
先定义一个Person类,有money属性,有say()方法
package com.gavin.oop.Demo05;
public class Person {
private int money;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void say() {
System.out.println("人类会说话");
}
}
再定义一个Student类,使用extends关键字继承Person类
package com.gavin.oop.Demo05;
public class Student extends Person{
public static void main(String[] args) {
Student student = new Student();
student.setMoney(100000000);
System.out.println("money=" + student.getMoney());
student.say();
}
}
执行结果:

Student类继承了Perosn类后,就拥有了Person类中的money属性和say方法,这就是继承的含义。Java中的继承为单继承,也就是说Student类继承了Person类后,就不能再继承其它的类了,而Person类还可以被其它的类继承。这就相当于现实生活中,一个儿子只有一个爹,而一个爹可以有多个儿子的道理一样。
super详解
super关键字用在Java的继承中,子类可以用super来调用类中的属性和方法
示例代码:
先定义一个Person类,有name属性,并赋值为张三,还有一个print方法
package com.gavin.oop.Demo05;
public class Person {
protected String name = "张三";
public void print() {
System.out.println("Person");
}
}
再定义一个Student类,也有name属性和print方法,给name属性赋值为李四
package com.gavin.oop.Demo05;
public class Student extends Person{
private String name = "李四";
public void print() {
System.out.println("Student");
}
public void test(String name) {
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
System.out.println("调用方法");
this.print();
super.print();
}
}
测试类中调用方法,并传入name参数的值为王五
package com.gavin.oop.Demo05;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("王五");
}
}
执行结果:

可以看出使用子类中使用super关键字,可以调用父类中属性和方法
使用super关键字的注意点:

方法重写
子类继承父类后,可以对父类中的方法进行重写,以便满足自己的需求
示例代码:
先创建一个B类对象,里面有一个test()方法
package com.gavin.oop.Demo05;
public class B {
public void test() {
System.out.println("B==>test()");
}
}
再创建一个A类对象用来继承B类,然后重写B类中的test()方法
package com.gavin.oop.Demo05;
public class A extends B{
@Override
public void test() {
System.out.println("A==>test()");
}
}
测试类代码:
package com.gavin.oop.Demo05;
public class Application {
public static void main(String[] args) {
A a = new A();
a.test();
//父类引用指向子类对象
B b = new A();
b.test();
}
}
执行结果:

可以看出B类和A的test()方法执行的结果都是一样的,原因就是A类重写了B类中的test()方法,使得B类中的test()方法和子类中test()方法一样
什么是多态

示例代码:
先创建一个Person对象,里面有一个run()方法
package com.gavin.oop.Demo06;
public class Person {
public void run() {
System.out.println("run");
}
}
再创建一个Student对象继承Person类,然后重写run()方法,再添加一个eat方法
package com.gavin.oop.Demo06;
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat() {
System.out.println("eat");
}
}
测试类代码:
package com.gavin.oop.Demo06;
public class Application {
public static void main(String[] args) {
/**
* 一个对象的实际类型是确定的,可以指向的引用类型就不确定了,父类的引用指向子类对象
*/
//Student 能调用的方法都是自己或者继承父类的
Student student = new Student();
//Person 夫类型 可以指向子类,但是不能调用子类中的方法
Person person = new Student();
student.run();
person.run();
//对象能执行哪些方法,主要看对象左边的类型,和右边的关系不大
student.eat();
//person.eat(); 父类中不能调用子类中的方法
}
}
执行结果:

多态注意事项:

instanceof关键字
instanceof关键字主要用来判断两个对象或者值,是否为同一类型,同一类型返回true,表示可以强制转换,不是同一类型就返回false,不能强行转换。

示例代码:
package com.gavin.oop.Demo06;
public class Person {
public void run() {
System.out.println("run");
}
}
package com.gavin.oop.Demo06;
public class Student extends Person{
}
package com.gavin.oop.Demo06;
public class Teacher extends Person{
}
package com.gavin.oop.Demo06;
public class Application {
public static void main(String[] args) {
/**
* Object -> Person -> Student
* Object -> Person -> Teacher
* Object -> String
*/
Object object = new Student();
System.out.println(object instanceof Student); //true
System.out.println(object instanceof Person); //true
System.out.println(object instanceof Object); //true
System.out.println(object instanceof Teacher); //true
System.out.println(object instanceof String); //true
System.out.println("===========================");
Person person = new Student();
System.out.println(person instanceof Student); //true
System.out.println(person instanceof Person); //true
System.out.println(person instanceof Object); //true
System.out.println(person instanceof Teacher); //false
//System.out.println(person instanceof String); 编译就报错,无法通过编译
}
}
可以看出,有父子继承关系的返回true,表示可以进行强制转换。
static关键字详解
static关键字可以用来修改变量,常量以及类中的方法,使用static修饰后不用创建对象,直接用对象名.来调用变量,常量和方法。
示例代码:
package com.gavin.oop.Demo07;
public class Student {
//静态变量
private static int age;
//非静态变量
private double score;
public static void main(String[] args) {
Student student = new Student();
//使用static可以直接使用类名调用
System.out.println(Student.age);
System.out.println(student.age);
System.out.println(student.score);
}
}
执行结果:

匿名代码块,静态代码块,构造方法的执行顺序
示例代码:
package com.gavin.oop.Demo07;
public class Person {
{
System.out.println("匿名代码块");
}
static {
System.out.println("静态代码块");
}
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person = new Person();
System.out.println("============");
Person person2 = new Person();
}
}
执行结果:

可以看出静态代码块最先执行,接着是匿名代码块,最后是构造方法,而且静态代码块只随着类加载执行一次。
静态导入包示例代码:
package com.gavin.oop.Demo07;
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
public static void main(String[] args) {
System.out.println(random());
System.out.println(PI);
}
}
执行结果:

静态导入包以后,使用方法时直接写方法名就可以调用。
抽象类

示例代码:
package com.gavin.oop.Demo08;
//用abstract修饰,表示抽象类
public abstract class Action {
//用abstract修饰,表示抽象方法
public abstract void doSoming();
//抽象类中也可以写蒲绒的方法
public void say() {
System.out.println("说话");
}
}
package com.gavin.oop.Demo08;
public class A extends Action{
//继承了抽象类要重写中没有实现的方法
@Override
public void doSoming() {
System.out.println("工作ing");
}
}
package com.gavin.oop.Demo08;
public class Application {
public static void main(String[] args) {
//new Action() 抽象类不能被实例化
//继承了抽象类的子类,才可以实例化
A a = new A();
a.doSoming();
}
}
执行结果:

抽象类的注意点:

接口的定义和实现

示例代码:
package com.gavin.oop.Demo09;
//interface 定义接口的关键字,接口都需要实现类实现
public interface UserService {
//定义接口中的方法
//接口中的所有定义都是抽象的 public static
void add(String name);
void update(String name);
void delete(String name);
void query(String name);
}
package com.gavin.oop.Demo09;
public interface TimeService {
void timer();
}
package com.gavin.oop.Demo09;
//类使用implements关键字实现接口
//实现了接口的类,就要重写接口中的方法
//可以利用接口实现多继承
public class UserUserviceImpl implements UserService, TimeService{
@Override
public void timer() {
}
@Override
public void add(String name) {
}
@Override
public void update(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void query(String name) {
}
}
接口的作用:

内部类

成员内部类示例代码:
package com.gavin.oop.Demo10;
public class Outer {
private int age = 10;
public void out() {
System.out.println("这是外部类的方法");
}
class Inner{
public void in() {
System.out.println("这是内部类的方法");
}
//获取外部类的私有属性
public void getAge() {
System.out.println(age);
}
}
}
package com.gavin.oop.Demo10;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getAge();
}
}
执行结果:

以上就是成员内部类的具体用法,其它的内部类可以自己试着写一下。
