Java 面向对象(详解)
一、面向对象
(1).面向对象编程(Object-Oriented Programming,OOP)
(2).面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
(3).面向对象是一种抽象的,具有主要的特征分别是封装、继承、多态、抽象
二、构造器(创建与初始化对象)
(1).使用new关键字创建对象)
(2).使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
(3).类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
1.必须和类的名字相同
2.没有返回类型,也不能写void
构造器必须掌握!!!在下面的代码示例中我们可以看到构造器的使用!!!
1、封装
是将东西包围起来通过自己想定义的方式获取。把过程和数据包围起来,对数据的访问只能通过已定义的界面。
代码示例:
package oop.Demo01;
//OopDemo01 类
public class OopDemo01 {
//main方法
public static void main(String[] args) {
System.out.println(max(10,50));//50
int max=OopDemo01.max(10, 100);
System.out.println(max);//100
}
/*
修饰符 返回值类型 方法名(...)
//方法体
//return 返回值
*/
public String sayHello(){
return "Hello World";//return 方法 返回一个结果
}
public static int max(int a,int b){
return a>b?a:b;
}
}
2、继承:
是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。使用关键字为extends
代码示例:
//子类:继承了父类,拥有父类的全部方法
package oop.Demo05;
//继承关系
//A extends B 父子关系 A是子类 B是父类
//子类A继承父类B
public class A extends B{
public static void main(String[] args) {
A a=new A();
a.test();//走的是A类的方法 输出A->test()
//父类的引用指向了子类
B b=new A();
b.test();//走的是A类的方法 输出A->test()
B c=new B();
c.test();//走的是B类的方法 输出B->test()
}
//重载是本类
//重写是子父类才有的
//Override重写的意思
@Override //注解:有功能的注解!
public void test() {
System.out.println("A->test()");
}
}
//父类
package oop.Demo05;
public class B {
public void test(){
System.out.println("B->test()");
}
}
注意点:
子类重写了父类的方法,刚才输出A B的时候是静态方法 static,静态方法与非静态方法的区别很大,静态方法;方法的调用只和左边,与定义类型有关,非静态方法:需要进行重写,重写的关键词只能是public 不能是private.若将public修改为private 则super不可调用,私有的不可被继承
super注意点:
1.super 调用父类的构造方法,必须在构造方法的第一个
2.super 必须只能出现在子类的方法或者构造方法中
3.super和this 不能同时调用构造方法
4.调用了父类的无参构造---super();这段代码时隐藏的
public Student() {
//而且如果要显示super();
//调用父类的构造器,必须要在子类的第一行
//this();也是一样 否则报错
super();
System.out.println("Student无参执行");
}
super与this对比
一、代表的对象不同:
1.this 本身调用这个对象
2.super 代表父类对象的引用
二、前提:
1.this 没有继承也可以使用
2.super 在继承条件下才可以使用
三、构造方法:
1.this() 本类的构造
2.super() 父类的构造
重写:需要有继承关系,子类重写父类的方法
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以扩大,但不能缩小 public>protected>default>private
4.抛出的异常:范围可以被缩小,但不能被扩大 ClassNotFoundException--->Exception(大)
重写;子类的方法和父类的方法必须一致,方法体不同!
为什么需要重写?
1.父类的功能 子类不一定需要 或者不一定满足!
重写快捷方法
1.alt+insert: 选中overring即可重写
3、抽象:
就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象包括两个方面,一是过程抽象,二是数据抽象。关键字为:sbstract
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类是抽象的,是对对象的抽象
从代码运行角度考虑是先有类后有对象,类是对象的模板
代码示例:
package oop.Demo08;
//抽象类的所有方法 继承了它的子类 都必须要实现它的方法 除非加上abstract
public abstract class A extends Action{
public void doSomething(){
}
}
package oop.Demo08;
//在一个类上面加上abstract即变成抽象类
//java的类是单继承
//但是接口可以是多继承
public abstract class Action {
public abstract void doSomething();
}
注意点:
1.abstract 抽象方法,只有方法名字,没有方法的实现。不能new这个抽象类只能靠子类去实现它!因为具有约束条件!
2.抽象类中可以写普通方法,抽象方法必须存在抽象类中
3.存在的意义:抽象出来,提高开发效率
4、多态
即同一方法可以根据对象的不用而采用多种不用的行为方式。一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
多态存在的条件:
1.有继承关系
2.子类重写父类的方法
3.父类引用指向子类对象
注意点:多态是方法的多态,属性没有多态。
代码示例:
//第一个java类
package oop.Demo06;
public class Application01 {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new person();
//当可以指向的引用类型就不确定了
// Student能调用的方法都是自己的或者继承父类的
Student01 s1=new Student01();
// Person父类型,可以指向子类,但是不可以调用子类独有的方法
Person01 s2=new Student01(); //父类的引用指向子类的
// Object s3=new Student01();
s2.run();
//子类重写了父类的方法,执行了子类的方法
s1.run();
//对象能执行哪些方法,主要看对象 左边的类型,和右边关系不大!
//s2.eat(); //子类重写了父类的方法,执行子类的方法
((Student01)s2).eat();//强转换类型,将s2强制转换位student类型
s1.eat();
}
}
//第二个java类
package oop.Demo06;
public class Person01 {
public void run(){
}
}
//第三个java类
package oop.Demo06;
public class Student01 extends Person01 {
//这里Student01继承了父类Person01的方法
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
三、instanceof(类型转换)引用类型
作用:判断一个对象是什么类型.
代码示例:
//第一个java类
package oop.Demo06;
import oop.Demo05.Person;
public class Application02 {
public static void main(String[] args) {
//1.类型之间的转换: 之前是基本类型转换 满足这个高低 64 32 16 8 低转高则强制
//2.类型之间的转换:父(高) 子(低)
//高--->低 不需要强制转换
// Object>String
// Object>Person>Teacher
// Object>Person>Student
Object object=new Student02();
// System.out.println(X instanceof Y);//能不能编译通过 取决于X与Y之间是否存在父子关系
System.out.println(object instanceof Student02); //true
System.out.println(object instanceof Person02); //true
System.out.println(object instanceof Object); //true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("==============================================");
Person02 person02=new Student02();
System.out.println(person02 instanceof Student02); //true
System.out.println(person02 instanceof Person02); //true
System.out.println(person02 instanceof Object); //true
System.out.println(person02 instanceof Teacher);//false
//System.out.println(person02 instanceof String);//编译报错
System.out.println("==============================================");
Student02 student02=new Student02();
System.out.println(student02 instanceof Student02); //true
System.out.println(student02 instanceof Person02); //true
System.out.println(student02 instanceof Object); //true
}
}
/*
父类指向子类的对象
把子类转换为父类,向上转型 (不用强制转换)
把父类转换为子类,向下转型 (需要强制转型)
方便方法的调用 减少重复的代码 简洁
抽象:编程思想
抽象 封装 继承 多态 ! 抽象--> 接口
*/
//第二个java
package oop.Demo06;
public class Person02 {
}
//第三个java
package oop.Demo06;
public class Student02 extends Person02 {
}
四、三种构造器
匿名构造器、静态构造器、方法构造器
以下为代码示例:
package oop.Demo07;
//Person被final定义了 则不能被继承 public final class Person
public class Person {
//匿名构造器
{System.out.println("匿名代码块");}
//静态构造器 只执行一次
static{System.out.println("静态代码块"); }
public Person(){System.out.println("构造器方法");}
public static void main(String[] args) {
Person person1=new Person();
//输出结果:静态代码块 静态代码块 静态代码块
System.out.println("=========================");
Person person2=new Person();
//静态构造器 只执行一次
//输出结果:匿名代码块 构造器方法
}
}
注意点:在java中是值传递的,代码示例:
package oop.Demo01;
public class OopDemo04 {
public static void main(String[] args) {
int a=1;
System.out.println(a);//1
OopDemo04.change(a);//无输出结果
System.out.println(a);//1
}
//这里的返回值为空 回到主函数
public static void change(int a){
a=10;
}
}
五、接口
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!(自己无法写方法~专业的约束!)
代码示例:
//第一个java类
package oop.Demo09;
public interface TimeService {
void timer();
}
//第二个java类
package oop.Demo09;
//interface 定义的关键字 接口都需要实现类
public interface UserService {
//定义常量---public static final
int age=99;
//接口中的所有定义都是抽象的
// 而且都是piblic abstract 若是不写默认都是piblic abstract
// public abstract void run();
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
//第三个java类
package oop.Demo09;
//抽象类:extends只能单继承
//类可以实现接口 implements 接口 可以多继承
//实现了接口中的类 就需要重写接口中的方法
// UserService,TimeService实现了多继承
//利用接口实现多继承
//接口里边只有方法的定义没有方法的使用
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 query(String name) {
}
@Override
public void timer() {
}
}
六、内部类
内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类
类别:
1.成员内部类
2.静态内部类
3.局部内部类
4.匿名内部类
//第一个java类
package oop.Demo10;
public class Application {
public static void main(String[] args) {
Outer outer=new Outer();
//使用内部类
//通过这个外部类来实例化内部类
Outer.Inner01 inner01=outer.new Inner01();
inner01.in();//输出这是内部类的方法
inner01.getID();//输出99
}
}
//第二个java类
package oop.Demo10;
public class Test {
public static void main(String[] args) {
//匿名类
//没有名字初始化类 ,不用将实例保存到变量中
new Apple().eat();
//Apple apple=new Apple(); new一个实例化对象
UserService userservice=new UserService(){
//没有名字初始化 需要重写
@Override
public void Hello() {
}
};
}
}
class Apple{public void eat(){
System.out.println("Apple");
}
}
interface UserService{
void Hello();
}
//第三个java类
package oop.Demo10;
public class Outer {
private int id=99;
public void out(){ System.out.println("这是外部类的方法"); }
public class Inner01{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
//加上static( public static class Inner)之后 这个id就拿不到了 若想要拿到 则 private static int id=99;即可
public void getID(){
System.out.println(id);
}
//局部内部类
public void method(){
class Inner02{
public void in(){
}
}
}
}
}
//一个java类中 可以有多个class类
//但是只能有一个public class类
class A{
public static void main(String[] args) {
System.out.println("你好");
}
}