面向对象编程是一种方法,被广泛引用与Java中
接下来我将从:包、继承、组合、多态、抽象类和接口这几个方面进行全面的讲解。
一、包
包是组织类的一种方式.
包从直观上看就是一个文件夹(jar包中包含的都是字节码文件).
包一般分为导入默认包、静态导入、和自定义导入三部分
导入默认包:
System.out.println(Arrays.toString(students));
当我们写这样一段代码时,Arrays不能直接使用,我们就需要导入java中的默认包来实现使用
import java.util.Arrays;
当我们还需要调用java.util中的其他包时我们可以将他们合并来使用
import java.util.*;
注意:java中对于包的调用是用那个调用那个。
静态导入:
在import后面加入static就为静态导入
import static java.lang.Math.*;
静态导入相较于其他导入来说可以更将方便的编写代码。
public static void main(String[] args) {
double x=30;
double y=20;
//静态导入之前
//double result=Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
//静态导入之后
double result=sqrt(pow(x,2)+pow(y,2));
}
自定义导入:
对于自定义导入包,就是我们自己进行编写一个类的实现,然后我们在其他的包中的类中去调用这个类。
package Test16;
import practice01.practice01;
public class Test01 {
public static void main(String[] args) {
practice01 practice01=new practice01();
}
}
常见的系统包:
1.java.lang:系统常用基础包(自动导入)
2.Java.lang.reflect:java反射编程包
3.java.net:进行网络编程开发包
4.java.sql:进行数据库开发的支持包
5.java.util:java的工具程序包
6.java.io:I/O编程开发包
二、继承
在这里我们首先要理解继承是为了干什么,继承是为了提高代码的使用率
class Animal{}
class Dog extends Animal{}
继承我们一般通过extends来实现
对于Animal我们一般叫做父类、基类,对于Dog我们一般叫做子类、派生类。
继承的思想就是通过extends抽取共性从而提高代码的重复使用率。
小结:java中有四种访问权限
private 只能在类内部进行访问,类外部不能访问。
默认访问权限(包访问权限) 只能在同一个包内进行访问。
protected 不仅可以在包内进行放访问,不同包类的子类也可以访问。
public 在任何情况下类的调用者都可以进行访问。
一般来说在继承中我们一般使用protrcted访问权限
复杂的继承关系:
class Animal{}
class Dog extends Animal{}
class Water extends Dog{}
class Microorganism extends Water{}
我们可以一直继承,但是我们一般最多继承三次;
三、final关键字和组合
3.1final关键字
final修饰的关键字修饰一个变量或者字段时,表示常量不能被改变
final int a=10;
a=20;//编译出错
final修饰类的时候类不能被继承
final class Animal{}
class Dog extends Animal{}//报错
3.2组合
组合不像extends那样,组合仅仅是将一个类的实例作为另外一个类的字段
class Student{}
class Teacher{}
class School{
public Student[] students;
public Teacher[] teachers;
}
四、多态
4.1向上转型
我们通过实例化一个对象通过父类引用这个对象叫做向上转型。
向上转型我们分为:直接赋值、方法传参、方法返回
class A{
void fly(){
System.out.println("wwwwwwwww");
}
}
class B extends A{
@Override
void fly(){
System.out.println("eeeeeeeee");
}
void size(){
System.out.println("发生了向下转型");
}
}
public class Test01 {
public static void main(String[] args) {
//A a=new B();
//a.fly();//发生了向上转型
//B b=new B();
//feed(b);//方法的传参
//方法的返回
//A a=find();
}
public static A find(){
B b=new B();
return b;
}
}
4.2向下转型
注意:向下转型一定是发生在向上转型之后。
class A{
void fly(){
System.out.println("wwwwwwwww");
}
}
class B extends A{
@Override
void fly(){
System.out.println("eeeeeeeee");
}
void size(){
System.out.println("发生了向下转型");
}
}
public class Test01 {
public static void main(String[] args) {
//向下转型
A a=new B();
B b=(B)a;
b.size();
//向下转型一定是发生了向上转型之后才能发生的
}
public static A find(){
B b=new B();
return b;
}
public static void feed(A a){
a.fly();
}
}
4.3动态绑定
当子类和父类中出现同名方法时
class Shape{
public void draw(){
System.out.println("m");
}
}
class Cycle extends Shape{
@Override
public void draw(){
System.out.println("Q");
}
}
Shape shape=new Shape();
Shape shape1=new Cycle();
shape.draw();;
shape1.draw();
我们发现他们调用的各自的draw方法
所以说要看这个引用指向的是父类还是子类对象,这个过程是运行时决定的,被称为动态绑定。
4.4重写
子类实现父类的同名方法,并且参数的类型和个数完全相同,这种情况称为重写。
class Shape{
public void draw(){
System.out.println("m");
}
}
class Cycle extends Shape{
@Override
public void draw(){
System.out.println("Q");
}
}
class Rect extends Shape{
@Override
public void draw(){
System.out.println("W");
}
}
public class Test02 {
public static void main(String[] args) {
Shape shape1=new Cycle();
Shape shape2=new Rect();
drawShape(shape1);
drawShape(shape2);
}
public static void drawShape(Shape shape){
shape.draw();
}
}
重写要注意的实项:
1、被final修饰的方法不能重写。
2、重写时子类的访问修饰权限要大于父类的权限
3、方法不能是static的
4.5理解多态
在我看来什么是多态,多态就是对于不同的调用者,我们调用的同一种方法可以表现出不同的形态,这种行为叫做多态。
package Test15;
class Animal{
public String name;
public Animal(String name){
this.name=name;
}
}
interface IFlying{
void Fly();
}
interface IRunning{
void Running();
}
interface ISwimming{
void Swimming();
}
class Cat extends Animal implements IRunning{
public Cat(String name) {
super(name);
}
@Override
public void Running() {
System.out.println(this.name+"正在快乐的奔跑");
}
}
public class Test05 {
public static void main(String[] args) {
Cat cat = new Cat("咪咪");
cat.Running();
}
}
五、抽象类
包含抽象方法的类我们叫做抽象类
abstract class Shape{
abstract public void drow();
}
注意:
1.抽象类中可以定义成员属性和成员方法
abstract class Shape{
int a;
void size(){}
abstract public void drow();
}
2.抽象类不能被实例化
3.抽象类存在的意义就是被继承,一个类如果继承了抽象类,那么他要重写它的所有方法;
4.抽象方法不能是final的且抽象方法不能是private的。
5.抽象类是可以发生向上转型和多态的
五、接口
接口里面的方法只能是抽象方法,方法的默认为pubilc abstract,接口中的成员变量默认为public static final
interface Shape{
abstract public void drow();
}
注意:在JDK1.8之后普通方法也可以加入接口,但是要在前面加入default
default void asd(){}
接口同样不能进行实例化
类和接口的关系需要通过implements来实现
interface Shape{
abstract public void drow();
default void asd(){}
}
class Shape01 implements Shape{
}
接口和接口的关系同样需要extends来继承
类可以继承多个接口但是需要用逗号隔开
接口也是可以发生向上转型和多态的
下面展示的是接口使用的例子:
package Test15;
class Animal{
public String name;
public Animal(String name){
this.name=name;
}
}
interface IFlying{
void Fly();
}
interface IRunning{
void Running();
}
interface ISwimming{
void Swimming();
}
class Cat extends Animal implements IRunning{
public Cat(String name) {
super(name);
}
@Override
public void Running() {
System.out.println(this.name+"正在快乐的奔跑");
}
}
public class Test05 {
public static void main(String[] args) {
Cat cat = new Cat("咪咪");
cat.Running();
}
}