目录
1包
1.1包的概念
包 (package) 是组织类的一种方式. 使用包的主要目的是保证类的唯一性
就是说当有两个类的类名相同时 ,我们可以采用定义在不同包的方式。通俗来讲,包就是一个文件夹。
1.2包的创建方法
在IDEA中,当我们创建好了项目之后我们之前都是直接在src下直接创建我们的类,那么包就是一同样的方法创建包,一般情况都是以公司域名的到写来表示。
例如:百度的域名是www.baidu.com(一般www.不用写),那我们的包名就是,baidu.com
这里我就是使用com.csdn.来作为示例了(包名要用小写)
1.3导入包中的类
当我们使用到其他的包中的类的时候我们就需用import进行导入
例如我们前面打印数组用到的Arrays类的时候我们就需要导入Arrays类的包
同样对我们自己定义的包同样可以导入
2继承
2.1继承的基本概念
继承是类与类之间的关系,继承的一方被成为子类,被继承的一方本成为父类。子类可以继承父类的属性和方法。在Java中用A extends B来表示A继承B.
代码中创建的类都是一种特定事物的抽象,但是在某些时候,这些个事物之间就有某种联系,那么表示这样的抽象的事物所对的类也就有了具体的关系。例如狗是一类事物,猫也是一类事物,但是它们之间都有一个共同的名字,那就是动物,所以我们就可以是使用继承的方式来表示。
2.2继承的基础语法
class A extends B{
}
2.3继承的使用
我们已经知道了继承的具体语法,那么具体应该怎么使用呢。那么我们现在来看看,一个例子。就拿刚才所说的狗和猫是动物的例子来说吧
我们定义一个Dog类
package com.csdn;
public class Dog {
private int age;
public Dog(int age, String name) {
this.age = age;
this.name = name;
}
private String name;
public void play(){
System.out.println("Playing_________");
}
}
然后在定义一个cat类
package com.csdn;
public class Cat {
private int age;
private String name;
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
public void play(){
System.out.println("Playing_________");
}
public void sleep(){
System.out.println("Sleeping_________");
}
}
我们可以观察到Dog类和Cat类中都有共同的属性age和name,有共同的方法play方法,那么我们就可以定义一个Animal类来包含他们共同的属性和方法
package com.csdn;
public class Animal {
private int age;
private String name;
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public void play(){
System.out.println("playing___________");
}
}
我们就可以让Dog类和Cat类继Animal类
package com.csdn;
public class Dog extends Animal {
public Dog(int age, String name) {
super(age, name);
}
public void play(){
System.out.println("Playing_________");
}
}
package com.csdn;
public class Cat extends Animal {
public Cat(int age, String name) {
super(age, name);
}
public void sleep(){
System.out.println("Sleeping_________");
}
}
我们把类似于Animal的类成为父类或者基类也称超类,将Dog和Cat这样的类成为子类或者派生类
此时我们来使用这两个类
我们可以发现我们并没有在Dog和Catl类中实现play方法,但是我们觉可以使用这个方法。说明我们的Dog类和Cat类继承了Animal类中的方法和属性
2.4重写
我们可以发现虽然我们Dog可以使用Play方法,但是当我们需要让Play实现,多大的什么名字的狗仔play的时候,就出现了问题,我们不能把他写在Animal类中,因为不是所有的动物都叫一个名字
。所以就引入了重写的概念
2.4.1重写的概念
子类继承父类,子类中实现和父类相同的方法,子类中的方法就会覆盖父类中相同的方法
2.4.2重写的特征
1.子类继承父类
2.子类中实现了和父类中方法名相同,返回值相同,参数列表相同的方法
3.子类中的方法覆盖父类中的方法。
4final修饰的方法不能被重写
5.static修饰不能被重写
6子类重写父类的方法,访问限制修饰符不能小于父类中该方法的访问限制修饰符
2.4.3访问权限
当我们想要去在子类中实现,多大的什么名字的狗正在玩时,我们发现,父类中的name和age并不能在子类中被访问,那么这是怎么搞回事呢。下面我们来探讨这个问题
1.protected权限访问修饰符
之前我们接触了public和private权限访问修饰符。现在介绍名一种权限访问修饰符,protected
protected权限访问修饰符,所修饰的方法和属性可以在同一包中的任意位置被访问,也可以不同包的子类中被访问。
2.default默认访问权限
default默认访问修饰权限是我们在方法和属性前面不加任何的访问修饰符的时候默认的权限
默认的权限也称为包访问权限,也就是说,可以在同一个包中的任何位置被访问,但是不能被不同包中的类所访问。
2.4.4重写的实例
那么基于权限访问我问题我们就将Animal类的private修饰的方法和属性改为哦protected的访问修饰权限
package com.csdn;
public class Animal {
protected int age;
protected String name;
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public void play(){
System.out.println("playing___________");
}
}
子类中重写play方法
package com.csdn;
public class Cat extends Animal {
public Cat(int age, String name) {
super(age, name);
}
public void sleep(){
System.out.println("Sleeping_________");
}
public void play(){
System.out.println(this.age+"岁的"+this.name+"爬树");
}
}
package com.csdn;
public class Dog extends Animal {
public Dog(int age, String name) {
super(age, name);
}
public void play(){
System.out.println(this.age+"岁的"+this.name+"正在玩足球");
}
}
这样不同的动物就可以实现不同的玩的功能了
2.5继承的注意事项
1.父类的构造方法不能被子类继承
2.父类的私有成员也不能被子类继承
3.构造子类对象时一定要先构造父类。
2.6super关键字
1.super是当前对象直接父类的引用
2.在子类中可以通过super来访问父类中的成员
3.子类中使用super()只能出现在子类构造方法的第条语句中。
4.this和super不能同时在构造方法中出现
3抽象类
我们可以发现我们的父类中所定义的方法并没有被使用,所以就没有实现的必要,所以将父类中的方法写为抽象方法,那么对应的抽象方法的类就是抽象类
3.1抽象类的概念
含有抽象方法的的类称为抽象类,用关键字abstract来修饰抽象类和抽象方法。
3.2抽象类的特性
1.抽象类不能实例化。
2.子类继承抽象类必须实现父类中所有的抽象方法
3.final修饰的类不能被继承,final修饰的方法不能被重写
4多态
4.1多态的概念
同一指令作用与不同对象,产生不同的效果的现象成为多态
4.2向上转型
为了解释向上转型我们给Animal增加一个方法叫做call方法,同时将Animal类定义为抽象类
package com.csdn;
public abstract class Animal {
protected int age;
protected String name;
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public abstract void play();
public abstract void call();
}
Cat类和Dog类继承Animal类并实现他的抽象方法
package com.csdn;
public class Cat extends Animal {
public Cat(int age, String name) {
super(age, name);
}
public void sleep(){
System.out.println("Sleeping_________");
}
public void play(){
System.out.println(this.age+"岁的"+this.name+"爬树");
}
@Override
public void call() {
System.out.println(this.age+"岁的"+this.name+"喵喵喵");
}
}
package com.csdn;
public class Dog extends Animal {
public Dog(int age, String name) {
super(age, name);
}
public void play(){
System.out.println(this.age+"岁的"+this.name+"正在玩足球");
}
@Override
public void call() {
System.out.println(this.age+"岁的"+this.name+"汪汪汪");
}
}
下面我们来看一段代码
我们可以看到此时我们用父类的引用,引用了子类的对象,那么这种现象就是向上转型。当然,现在肯定会有一个疑问,就是:不是说抽象类不能实例化对象吗,那么为什么这里可以呢。
这里我们需要注意的是:这里我只定义了Animal的引用类型变量,并没有实例化Animal的对象,在Java中,实例化对象就是new的过程。
4.3动态绑定
我们是不是有这样的一个疑问,当程序调用call方法时,为什么就会知道调用那个方法呢,其实,在编译的过程中绑定的是父类的call方法在程序运行的过程中绑定的是具体子类的方法。
4.4向上转型发生的时机
1.直接将子类对象赋值给父类引用
2.子类对象作为实参,父类引用作为形参
3子类对象作为函数返回值,用父类引用接收
4.5多态的实现
我们来看下面这段代码
同样是一个animalCall的指令,分别左右在了dog和cat的不同对象身上产生了不同的效果,这就多态。
4.6多态发生的条件
1.有继承关系
2.子类重写父类的方法
3.父类引用,指向子类对象
4.7多态的目的
1.为了提高代码的可扩展性和可维护性
2.方便代码逻辑的编写
4.8多态实现的两种形式
1.父类作为方法的参数
2.父类作为方法的返回值
5接口
5.1接口的基本概念
接口是一类事物所具有的的功能的抽象,用interface修饰。
5.2接口的基本语法
public interface Interface{
//具体的方法
}
5.3接口的用法
1.使用interface来修饰
2.接口中可以包含多个方法,接口中的方法一般都是抽象方法,接口中不能实现抽象方法。要想实现接口中的方法了,必须使用default默认权限来修饰。
3.子类实现接口使用implements关键字实现,子类必须实现接口中的所有抽象方法。
5.3接口的特征
1.子类必须实现接口中的所有方法
2.子类可以实现多个方法
3.接口不可以实例化对象
4.接口中不能包含构造方法
5.接口中的方法默认是public abstract 修饰,属性默认是public static final修饰
5.4接口的好处
接口是一种约定,设计程序时面向接口的约定,而不用关系接口的实现细节。
5.5接口和抽象类的区别
1子类在继承抽象类的时候必须实现抽象类中的所有抽象方法,普通方法可以不实现。但是在实现接口的时候必须实现接口中的所有方法。
2.抽象类中可以定义成员变量,但是接口中的成员变量都是静态常量
3.子类只可以继承一个抽象类但是子类可以实现多个接口
4抽象类和接口都不能实例化对象,但是抽象类中可以有构造方法,但是接口中不能有构造方法。
5抽象类可以实现方但是不用实现接口中方法,接口只能继承接口,但是不能实现接口。
5.6接口的使用示例
我们在这里定义一个基类Animal定义三个派生类,Dog,Duck,Frog,定义三个接口Fly,Run,Swimming。Dog,Duck,Frog类继承于Animal类,Dog类实现Run接口,Duck类实现Run,Swimming,Fly接口,Frog类实现Swimming,Run接口
package Interface;
public class Animal {
private String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println(this.age+"岁的"+this.name+"在吃");
}
}
package Interface;
public class Dog extends Animal implements Run{
public Dog(String name, int age) {
super(name, age);
}
@Override
public void run() {
System.out.println(this.getAge()+"岁的"+this.getName()+"正在跑");
}
}
package Interface;
public class Duck extends Animal implements Run,Flay,Swimming{
public Duck(String name, int age) {
super(name, age);
}
@Override
public void fly() {
System.out.println(this.getAge()+"岁的"+this.getName()+"正在飞");
}
@Override
public void run() {
System.out.println(this.getAge()+"岁的"+this.getName()+"正在跑");
}
@Override
public void swimming() {
System.out.println(this.getAge()+"岁的"+this.getName()+"正在游泳");
}
}
package Interface;
public class Frog extends Animal implements Swimming,Run{
public Frog(String name, int age) {
super(name, age);
}
@Override
public void run() {
System.out.println(this.getAge()+"岁的"+this.getName()+"正在跑");
}
@Override
public void swimming() {
System.out.println(this.getAge()+"岁的"+this.getName()+"正在游泳");
}
}
package Interface;
public interface Flay {
void fly();
}
package Interface;
public interface Run {
void run();
}
package Interface;
public interface Swimming {
void swimming();
}
我们可以实现让程序让会飞的可以飞等操作
package Interface;
public class Test {
public static void fly(Flay flay){
flay.fly();
}
public static void run(Run run){
run.run();
}
public static void swim(Swimming swimming){
swimming.swimming();
}
public static void main(String[] args) {
Dog dog=new Dog("小狗",19);
run(dog);
Duck duck=new Duck("小鸭",20);
run(duck);
fly(duck);
swim(duck);
Frog frog=new Frog("青蛙",4);
run(frog);
swim(frog);
}
}
现在我们再来定义一个类Robot类,让它实现Run方法
package Interface;
public class Robot implements Run {
private String name;
private int age;
public Robot(int age, String name){
this.name=name;
this.age=age;
}
@Override
public void run() {
System.out.println(this.age+"岁的"+this.name+"正在跑");
}
}
我用只需要让它调用run方法,就可以实现跑的功能
package Interface;
public class Test {
public static void fly(Flay flay){
flay.fly();
}
public static void run(Run run){
run.run();
}
public static void swim(Swimming swimming){
swimming.swimming();
}
public static void main(String[] args) {
Dog dog=new Dog("小狗",19);
run(dog);
Duck duck=new Duck("小鸭",20);
run(duck);
fly(duck);
swim(duck);
Frog frog=new Frog("青蛙",4);
run(frog);
swim(frog);
Robot robot=new Robot(20,"机器人");
run(robot);
}
}
综上而言,接口可以让具有同种功能的事物去实现接口,而达到接口所对应的功能。增强了代码的可扩展性和可维护性。