JAVA基础5:面向对象
1、面向对象
- OOP(Object Oriented Programming):面向对象编程
- 以类(抽象的,对象的模板)的方式组织代码,以对象(具体的)的方式封装数据
- 特性
- 封装
- 继承
- 多态
//Demo01 类
public class Demo01 {
//main 方法
public static void main(String[] args) {
}
/* (参数类型 参数名)
修饰符 返回值类型 方法名(参数列表){
...
方法体
return 返回值;
}
*/
public String sayhello(){
return "hello,world!";
}
public int max(int a,int b){
return a>b ? a : b;
}
public void hello(){
return;
}
}
//学生类
public class Student {
//静态方法
public static void say(){
System.out.println("说悄悄话!");
}
//非静态方法
public void run(){
System.out.println("到处乱跑!");
}
}
public class Demo02 {
public static void main(String[] args) {
//静态方法可以直接调用
//方便外部直接调用,和类一起加载
Student.say();
/*
非静态方法需要实例化:new 类
为了更好的封装,避免外部直接调用,实例化后才存在
对象类型 对象名 = new 类 ;
快捷方式: new 类 + Alt+\n + \n
*/
Student student = new Student();
student.run();
}
}
2、类与方法
//以类的方式组织代码
public class Student {
//属性
String name; //默认值:null
int age; //默认值:0
//方法
public void study(){
System.out.println(this.name + "在学习!");
}
}
//以对象的方式封装数据
public class Application {
public static void main(String[] args) {
/*
把抽象的Student类实例化
实例化后会返回一个自己的对象student
对象*是一个Student类的具体实例!
*/
Student hurry = new Student();
Student sendoh = new Student();
hurry.name = "Hurry";
sendoh.name = "Sendoh";
hurry.age = 10;
sendoh.age = 40;
System.out.println(hurry.name);
System.out.println(hurry.age);
System.out.println(sendoh.name);
System.out.println(sendoh.age);
}
}
3、构造器
public class Person {
/*
一个类即使什么都不写,他也存在一个方法-->构造器(构造方法)
快捷方式:Alt + insert
构造器的2个特点:
1、必须和类的名字相同,
2、必须没有返回类型,也不能写void
class文件将生成:
public Person(){
}
*注意*一旦定义了有参构造,就必须有无参构造!
*/
String name;
public Person(String name){
this.name = name; //this.表示当前类的*
}
public Person() {
}
}
public class Application {
public static void main(String[] args) {
/*
1、类若为空:
实例化(new 类)后,系统默认调用构造器!用来初始化值
2、类中一旦定义了有参构造,就必须有无参构造!否则实例化报错!
*/
Person person = new Person();
Person harry = new Person("Harry");
System.out.println(person.name);
}
}
4、封装
- 高内聚、低耦合
- 属性私有,get/set
public class Student {
//属性私有 private
private String name; //名字
private int id; //学号
private char sex; //性别
/*封装
提供一些public的方法:set、get方法
快捷方式:Alt + Insert+\n +选择
封装的作用:
1、提高程序的安全性,保护数据
2、隐藏代码的实现细节
3、统一接口
4、增强系统可维护性
*/
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 class Application {
public static void main(String[] args) {
Student harry = new Student();
harry.setName("Harry");
harry.setId(40);
System.out.println(harry.getName());
System.out.println(harry.getId());
}
}
5、继承
- entends:扩展,子类是父类的扩展。
- Java中只有单继承,没有多继承
//学生类:派生类、子类
public class Student extends Person {
/*
子类继承父类,就是拥有父类的全部方法和public属性
快捷方式:Ctrl+h
*/
private String name = "学生";
public void test(String name){
System.out.println(name); //传参
System.out.println(this.name); //本类
System.out.println(super.name); //继承
}
}
/*
人类:父类
Java中,所有的类都继承Object类
*/
public class Person {
protected String name = "人类";
}
public class Application {
public static void main(String[] args) {
Student harry = new Student();
harry.test("Harry");
}
}
-super
区别 | super | this |
---|---|---|
引用对象 | 父类对象的引用 | 本省调用者的对象 |
前提 | 只能在继承条件下使用 | 没有继承也能使用 |
构造方法 | 父类的构造 | 本类的构造 |
6、多态
- 同一方法可以根据发送对象的不同而采用不同的行为方式
- 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
- 方法的多态,属性没有多态
- 父子类必须有关系,才能转换,不然会出现ClassCastException!(类型转换异常)
- 继承关系,方法需要重写,父类引用指向子类对象:Father f1 = new Son();
public class Student extends Person {
@Override
public void run() {
System.out.println("疯跑打闹!");
}
public void read(){
System.out.println("看书!");
}
}
public class Person {
public void run(){
System.out.println("run");
}
}
public class Application {
public static void main(String[] args) {
Student ss = new Student(); //子类型:可调用子类或父类的方法
/*多态
一个对象指向的引用类型可以不同:父类的引用指向
对象能执行那些方法,与对象类型(左边)相关!
*/
Person ps = new Student(); //父类型:可以指向子类,但不能调用子类独有的方法
Object os = new Student();
/*父类定义的方法、子类没有:
若子类没有重写,就调用父类的run()方法
若子类重写,就调用子类的run()方法
*/
ps.run();
ss.run();
/*子类定义了方法,父类没有:
父类不可调用子类独有的方法:ps.read();
只能用强制转换的方法转化(高转低):((Student) ps).read();
*/
ss.read();
((Student) ps).read();
}
}
public static void main(String[] args) {
/*
Object > Person > Student
Object > Person > Teacher
Object > String
System.out.println(x instanceof y);-->能否编译报错看出是否有继承关系
*/
Object os = new Student();
System.out.println(os instanceof Student); //true
System.out.println(os instanceof Person); //true
System.out.println(os instanceof Object); //true
System.out.println(os instanceof Teacher); //false
System.out.println(os instanceof String); //false
System.out.println("==================");
Person ps = new Student();
System.out.println(ps instanceof Student); //true
System.out.println(ps instanceof Person); //true
System.out.println(ps instanceof Object); //true
System.out.println(ps instanceof Teacher); //false
//System.out.println(ps instanceof String); //编译报错
System.out.println("==================");
Student ss = new Student();
System.out.println(ss instanceof Student); //true
System.out.println(ss instanceof Person); //true
System.out.println(ss instanceof Object); //true
//System.out.println(ss instanceof Teacher); //编译报错
//System.out.println(ps instanceof String); //编译报错
}
- static(类)、final(常量,方法定义后无法继承),private(私有方法)不能使用多态
public class Student {
private static int age; //静态的变量
private double score; //非静态的变量
public static void go(){ //静态方法
}
public void run(){ //非静态方法
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(Student.age);
System.out.println(s1.age);
System.out.println(s1.score);
go();
//非静态方法无法直接引用run();
}
}
public class Person {
//第2个执行,每次都执行!设一些初始值
{
System.out.println("匿名代码块");
}
//第1个执行,只执行一次!
static{
System.out.println("静态代码块");
}
//第3个执行,每次都执行
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Person p1 = new Person();
System.out.println("=============");
Person p2 = new Person();
}
}
/*结果:
静态代码块 //1
匿名代码块 //1
构造方法 //1
=============
匿名代码块 //2
构造方法 //2
*/
//静态导入包 static
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);
}
}
7、抽象类
- abstract抽象的抽象,就是一种约束
- 不能new出实例,只能靠子类去实现它
- 抽象类中可以写普通的方法
- 抽象的方法必须在抽象类中
//抽象类,单继承。(接口才能多继承)
public abstract class Action {
//抽象方法:只有方法名,没有方法的实现。
public abstract void doOneThing();
}
8、接口
- interface,接口就是契约,规范,定义方法让不同人实现
- 抽象类的抽象,可以多继承,但必须重写接口中的方法
- 接口中没有构造方法,不能new实例化
public interface UserService {
//接口中所有的定义都是抽象的,不用写:public abstract
//返回类型 方法名
void add(String name);
void del(String name);
void set(String name);
void get(String name);
}
public interface TimeSevice {
void time();
}
//实现接口的类,必须要重新接口中方法
//接口可以多继承
public class UserServiceImpl implements UserService , TimeSevice {
@Override
public void add(String name) {
}
@Override
public void del(String name) {
}
@Override
public void set(String name) {
}
@Override
public void get(String name) {
}
@Override
public void time() {
}
}