1.回顾方法
package com.lin.study.oop.demo01;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名(...){
//方法体
return 返回值;
}
*/
//return : 结束方法,返回一个结果
public String sayHello(){
return "Hello world!";
}
public void print(){ //void表示没有返回值
return;//只能返回空
}
public int max(int a,int b){
return a > b ? a : b;
}
public void readFile(String file) throws IOException{
}
}
2.类与对象的创建
知识小店: 面向对象的本质: 以类的方式组织代码,以对象的形式封装数据
package com.lin.study.oop.demo02;
public class Student {
//属性: 字段
public String name;//null
public int age; //0
//方法
public void study(){
System.out.println(this.name + "在学习");
}
}
/*
package com.lin.study.oop;
import com.lin.study.oop.demo02.Student;
public class Application {
public static void main(String[] args) {
*/
/*//*
/类 : 抽象的
//类实例化后会返回一个自己的对象
//xiaoming对象,就是Student类的具体实例
Student xiaoming = new Student();
Student xh = new Student();
xiaoming.name = "小明";
xiaoming.age = 3;
System.out.println(xiaoming.name);//小明
System.out.println(xiaoming.age);//3
xh.name = "小红";
xh.study();//小红在学习*//*
}
}
*/
3.构造器
package com.lin.study.oop.demo02;
public class Person {
//一个类中即使什么都没写,它也会存在一个空构造方法
public String name;
//构造器用于实例化初始值。
//使用new关键字,其本质是在调用构造器。
//1.一个无参数的构造器
public Person(){
this.name = "狂神";
}
//2.一个有参数的构造器
//一旦定义了有参数的构造器,还想使用无参构造,就必须显式的定义一个无参构造
public Person(String name){
this.name = name;
}
//Alt + insert : 快捷生成构造器
}
/*
package com.lin.study.oop;
import com.lin.study.oop.demo02.Person;
public class Application {
public static void main(String[] args) {
//new : 实例化了一个对象
Person p = new Person();
System.out.println(p.name);//狂神
Person p2 = new Person("狂神2");
System.out.println(p2.name);//狂神2
}
}
*/
构造器总结:
和类名相同
没有返回值
作用:
new 的本质是在调用方法
初始化对象的值
注意点:一旦定义了有参数的构造器,还想使用无参构造,就必须显式的定义一个无参构造
//Alt + insert : 快捷生成构造器
package com.lin.study.oop.demo03;
public class Pet {
public String name;
public int age;
public void shout(){
System.out.println("叫了一声");
}
}
/*package com.lin.study.oop;
import com.lin.study.oop.demo03.Pet;
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();//狗对象
Pet cat = new Pet();//猫对象
dog.name = "旺财";
dog.age = 3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
}
}*/
4.类与对象小结
1.类与对象
类是一个抽象的模板
对象是一个具体的实例
2.方法
定义 调用
3.对应的引用
引用类型: 对象是通过引用来操作的
4.属性: 字段 成员变量
默认初始化值
数字: 0 或 0.0
char: u0000
boolean: false
引用: null
5.对象的创建和使用
-
必须使用new关键字创建对象:Person p = new Person();
-
对象的属性: p.name
-
对象的方法: p.sleep()
6.类
静态的属性<------->属性
动态的行为<------->方法
5.封装
程序设计追求: "高内聚,低耦合"
package com.lin.study.oop.demo04;
public class Student {
//属性私有
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;//年龄
//提供一些可以操作这个属性的方法
//提供一些public 的 get,set 方法
//get: 获得数据
public String getName(){ return this.name; }
public void setName(String name){ this.name = name;}
//快捷生成get,set方法 : Alt + insert
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;
}
//get,set方法的好处 : 可以通过方法体对属性进行限制
public int getAge(){ return age; }
public void setAge(int age){
if (age>120||age<0){//属性不合法
this.age = 3;
}else{
this.age = age;
}
}
}
/*
package com.lin.study.oop;
import com.lin.study.oop.demo04.Student;
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("林");
System.out.println(s1.getName());//林
s1.setAge(-1);//属性设置不合法
System.out.println(s1.getAge());//3
}
}
*/
封装的好处:
提高程序的安全性保护数据
隐藏代码的实现细节
统一接口
系统可维护性增加了
6.继承
1.简单概念
父类
package com.lin.study.oop.demo05;
public class Person {
public int money = 10_0000_0000;
public void say(){
System.out.println("说了一句话!");
}
}
子类
package com.lin.study.oop.demo05;
public class Student extends Person{
//这里什么都没有写
//只是继承了Person类
}
测试类
package com.lin.study.oop;
import com.lin.study.oop.demo05.Student;
public class Application {
public static void main(String[] args) {
Student s = new Student();
s.say();//说了一句话
System.out.println(s.money);//1000000000
}
}
知识总结;
Ctrl + H :查看继承关系
学生 is 人: 派生类,子类
子类继承了父类,就会拥有父类的全部方法。
在Java中,所有的类,都默认直接或间接的继承Object类
私有的东西无法被继承。
2.super详解
父类
package com.lin.study.oop.demo06;
public class Person {
//区块1
//构造方法
public Person() {
System.out.println("这里是Person父类的无参空构造!");
}
//区块2
//定义属性
protected String name = "尚学堂";
//区块3
public void print(){
System.out.println("这是父类的方法!");
}
}
子类
package com.lin.study.oop.demo06;
public class Student extends Person{
//区块1
//构造方法
public Student() {
//隐藏代码super: 调用了父类的无参空构造
//super();//这里会调用父类的无参空构造,这里不写super也会先调用父类的空构造
System.out.println("这里是Student子类的无参空构造!");
}
//区块2
//定义属性
private String name = "狂神";
public void test(String name){
System.out.println(name);//林
System.out.println(this.name);//狂神
System.out.println(super.name);//尚学堂
}
//区块3
@Override
public void print() {
System.out.println("这里是子类的方法!");
}
public void test2(){
//这两个此时调用的是相同的方法!
print();//这里是子类的方法!
this.print();//这里是子类的方法!
super.print();//这里是父类的方法!
}
}
测试类
package com.lin.study.oop;
import com.lin.study.oop.demo06.Student;
public class Application {
public static void main(String[] args) {
//区块1
Student s = new Student();
//区块2
s.test("林");
//区块3
s.test2();
}
}
知识总结:
super注意点:
super 调用父类的构造方法,必须在构造方法的第一行!
super 只能出现在子类的方法或构造方法中!
super 和 this不能同时调用构造方法!
对比this关键字:
代表的对象不同
this: 调用本身这个对象
super: 代表父类对象的引用
前提:
this: 没有继承也可以使用
super: 只能在继承条件下使用
构造方法:
this() : 调用本类的空构造器
super() : 调用父类的空构造器
3.方法重写
父类
package com.lin.study.oop.demo07;
public class B {
//静态方法
public static void test(){
System.out.println("B的静态方法!");
}
public void test2(){
System.out.println("B的非静态方法!");
}
}
子类
package com.lin.study.oop.demo07;
public class A extends B{
//静态方法
public static void test(){
System.out.println("A的静态方法!");
}
@Override
public void test2() {
System.out.println("A的非静态方法!");
}
}
测试类
package com.lin.study.oop;
import com.lin.study.oop.demo07.A;
import com.lin.study.oop.demo07.B;
public class Application {
public static void main(String[] args) {
//方法的调用
A a = new A();
a.test();//A的静态方法!
a.test2();//A的非静态方法!
B b = new A();
b.test();//B的静态方法!
b.test2();//A的非静态方法!
}
}
知识总结:
静态方法和非静态方法区别很大!
静态方法: 方法的调用之和左边的数据类型有关。
非静态方法: 重写
重写: 需要有继承关系,子类重写父类的方法!
方法名必须相同
参数列表必须相同
修饰符: 范围可以扩大但不能缩小: public > protected > default > private
抛出的异常: 范围可以被缩小,但不能被扩大!
重写中子类的方法和父类的方法必须一致,方法体不同
为什么需要重写:
父类方法的功能,子类不一定需要,或者不一定满足!
Alt + Insert : override : 重写快捷键。
7.多态
父类Person
package com.lin.study.oop.demo07;
public class Person {
//父类中的一个方法
public void run(){
System.out.println("父类的run方法!");
}
public void sleep(){
System.out.println("这是父类特有的方法!");
}
}
子类Student
package com.lin.study.oop.demo07;
public class Student extends Person{
//在子类中重写run方法
@Override
public void run() {
System.out.println("在子类中重写的run方法!");
}
//定义一个子类特有的方法
public void eat(){
System.out.println("这是子类特有的eat方法!");
}
}
测试类Application
package com.lin.study.oop;
import com.lin.study.oop.demo07.Person;
import com.lin.study.oop.demo07.Student;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//eg: new Student(); new Person();
//而可以指向的引用类型就不是确定的了
//父类的引用指向子类
//Student子类,能调用的都是自己的,或者继承父类的
Student s1 = new Student();
//Person父类型 可以指向父类,但不能调用子类中独有的方法
Person s2 = new Student();
Object s3 = new Student();
//1.父类中的run方法,并且子类进行了重写
s1.run();//输出: 在子类中重写的run方法!
s2.run();//输出: 在子类中重写的run方法!(子类重写了父类的方法,则执行子类重写后的方法)
//2.调用子类中特有的eat方法
s1.eat();//输出: 这是子类特有的eat方法!
//s2.eat();//错误!这里无法调用!
((Student)s2).eat();//将s2强制向下转换为Student类型,才可以调用子类中特有的eat方法
//3.父类中的sleep,且子类未重写
s1.sleep();//输出: 这是父类特有的方法!(子类可以正常调用)
s2.sleep();//输出: 这是父类特有的方法!(父类可以正常调用)
}
}
多态知识总结:
多态是方法的多态,属性没有多态。
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大。
存在条件: 有继承关系,方法需要重写,父类引用指向子类对象。
Father f1 = new Son();
无法重写的方法
static方法,它属于类,不属于实例。
final 常量修饰符修饰的方法。
private 修饰的方法。
8. instanceof 关键字
//instanceof 关键字: 检查一个对象是否由指定类定义
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object o = new Student();
System.out.println(o instanceof Student);//T
System.out.println(o instanceof Person);//T
System.out.println(o instanceof Object);//T
System.out.println(o instanceof Teacher);//F
System.out.println(o instanceof String);//F
Person p = new Student();
System.out.println(p instanceof Student);//T
System.out.println(p instanceof Person);//T
System.out.println(p instanceof Object);//T
System.out.println(p instanceof Teacher);//F
System.out.println(p instanceof String);//编译出错!
Student s = new Student();
System.out.println(s instanceof Student);//T
System.out.println(s instanceof Person);//T
System.out.println(s instanceof Object);//T
System.out.println(s instanceof Teacher);//编译出错!
System.out.println(s instanceof String);//编译出错!
9.引用类型转换
父类Person
package com.lin.study.oop.demo07;
public class Person {
//父类中的一个方法
public void run(){
System.out.println("父类的run方法!");
}
}
子类Student
package com.lin.study.oop.demo07;
public class Student extends Person{
//定义一个子类特有的方法
public void eat(){
System.out.println("这是子类特有的eat方法!");
}
}
测试类Application
package com.lin.study.oop;
import com.lin.study.oop.demo07.Person;
import com.lin.study.oop.demo07.Student;
public class Application {
public static void main(String[] args) {
//引用类型之间的转换: 父类和子类
//1.由高到低转: 强制转换
Person obj = new Student();
//只有将对象obj转换为Student类型,对象obj才可以调用子类的eat方法
Student s = (Student)obj;
s.eat();//这是子类特有的eat方法!
//两句代码合成一句
//((Student)obj).eat();//这是子类特有的eat方法!
//2.由低到高: 自动实现
Student s2 = new Student();
s2.eat();//此时未转换
Person p = s2;//自动将s2转换为高类型Person
((Student)p).eat();//此时强制再转换回去才可以调用eat方法
}
}
子类转换为父类: 向上转型 : 自动实现
父类转换为子类: 向下转型 : 强制转换
10. static 关键字
package com.lin.study.oop.demo07;
public class Student {
//1.属性
private static int age;//静态的变量
private double score;//非静态的变量
//2.方法
public static void go(){}//静态方法
public void run(){}//非静态方法
public static void main(String[] args) {
//1.属性
Student s1 = new Student();
//静态的变量可以直接通过 类名.变量名 调用
System.out.println(Student.age);
//System.out.println(Student.score);//非静态的变量不可以这样调用
System.out.println(s1.age);
System.out.println(s1.score);
//2.方法
go();//正确: 静态方法可以调用静态方法
//run();//错误: 静态方法不可以调用非静态方法
}
}
package com.lin.study.oop.demo07;
public class Person {
public Person(){
System.out.println("构造方法");
}
{
System.out.println("匿名代码块");
}
static {
System.out.println("静态代码块");
}
public static void main(String[] args) {
Person p = new Person();
//执行顺序: 静态 > 匿名 > 构造
//静态static 只会执行一次
}
}
11. 抽象类
父类 : Action
package com.lin.study.oop.demo08;
//abstract 抽象类 : extends : 单继承
public abstract class Action {
//abstract 抽象方法 只有方法名字,没有方法实现!
public abstract void doSomething();
}
子类 : A
package com.lin.study.oop.demo08;
public class A extends Action {
//子类继承了抽象类,就要重写它的所有方法,除非子类也是抽象类
@Override
public void doSomething() {
}
}
抽象类总结 :
不能new这个抽象类,只能靠子类去实现它 : 约束!
抽象类也可以写普通的方法。
但抽象方法必须存在于抽象类中。
12. 接口
接口1 : UserService
package com.lin.study.oop.demo09;
//interface 定义接口的关键字,接口都需要有实现类。
public interface UserService {
//1.接口中的常量,默认为由 public static final 修饰
int AGE = 99;
//2.接口中的方法,默认为由 public abstract 修饰
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
接口2 : TimeService
package com.lin.study.oop.demo09;
public interface TimeService {
void time();
}
实现类 : UserServiceImpl
package com.lin.study.oop.demo09;
public class UserServiceImpl implements UserService,TimeService{
//TimeService中的方法
@Override
public void time() {
}
//UserService中的方法
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
接口知识总结:
类可以实现接口: implements 接口
实现了接口的类,就需要重写接口中的方法。
利用接口可以实现 伪多继承(多实现)。
接口不能被new实例化,接口中没有构造方法。
implements 可以实现多个接口。
13. 内部类
成员内部类
package com.lin.study.oop.demo10;
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类的方法!");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法!");
}
//成员内部类可以获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
}
测试类
package com.lin.study.oop;
import com.lin.study.oop.demo10.Outer;
public class Application {
public static void main(String[] args) {
Outer o = new Outer();
//通过这个外部类的实例来实例化内部类
Outer.Inner i = o.new Inner();
i.in();//这是内部类的方法!
i.getID();//10
}
}