包
包(package)组织类的一种方式!
使用包的目的:使类具有唯一性!
包是组织类的一种方式,我们java中的多个类可以放到一个包中。
就好比学校里的班级就是一个包,我们学生就是一个类,相同班级的我们都放在同一个包下!
目的:使类具有唯一性!
就是说不同包下的类我们可以有同名的类,如果没有包的话,类名相同,类就无法区分,不唯一!就好比我们填写我们的信息不止填姓名,还会加上班级等进行限定!
无法在一个包下创建相同类名的类!
在不同的包下,我们可以创建相同类名的类,所以类保证了类的唯一性!我们可以看到
我们的Test类在demo_1和demo两个包下都有!
但是我们可以看到两个类的第一行都有声明在那个包下的类!
语法格式
package 包名;
在demo_1包下的Test类
在demo_2下的Test类
包的命名方法
我们java一般采用域名命名法!
例如我们可以用我们的邮箱域名命名我们的包
eg: 域名:bugguo.qq.com
那我的包名就可以以com.qq.buguo命名!
我们可以看到.将一个包分成了多层文件夹!
所以也可以说包就是一个文件夹!
命名规范
所有命名规则必须遵循以下规则:
1)、名称只能由字母、数字、下划线、$符号组成
2)、不能以数字开头
3)、名称不能使用JAVA中的关键字。
4)、坚决不允许出现中文及拼音命名。
导入包中的类
java下提供了很多写好的类给我们使用,这也是java便利快捷的编写java程序!
import关键字:
顾名思义:import有导入输入的意思
我们可以通过import关键字导入系统中的类
我们有时可能不止使用java.util下的一个类,但我们要使用多个类时!
值得注意的是java并不是像C语言下的#include一样,java下的导入包中的类,并不会真正的将该包下的全部内容全部导入到代码中,而是该代码会使用到的类java才会去真正意义导入!
所以不要有整体导入包就会使java代码效率更低的顾虑!
当一个类在不同的包下时
我们已经知道了,java中的包目的就是:使类具有唯一性!
但我们使用java类是两个包下都有该类时,我们就需要正确完整导入该类。
不能整体导入,否者会产生编译错误!
系统包的介绍
我们java下已经写好了很多系统包,但我们要使用到某个功能时,只需要将该包下的类导入即可!
java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
java.lang.reflect:java 反射编程包;
java.net:进行网络编程开发包。
java.sql:进行数据库开发的支持包。
java.util:是java提供的工具程序包。(集合类等) 非常重要
java.io:I/O编程开发包。
可以看到我们就接触了java.util工具包,最常用!
以后的系统包。我们会一一接触!
注意事项
import关键字并不可以导入指定的某个包,
它的作用是导入包中的类,如果要将该包下所有的类导入,就使用.*代替该包下的所有类!
继承
顾名思义java继承就是和我们所说的继承应该是一样的,子女继承父母!
java继承也是如此,java类可以继承父类!~
//简单的一个继承代码! //父类 class Animal{ public String name; public String age; } class Dog extends Animal{ //extends继承了父类Animal //Dog类就有了父类Animal的属性 //name和age } public class Test { public static void main(String[] args) { Dog dog = new Dog(); //创建一个Dog对象 dog.name = "bug郭"; //给继承的属性赋值 dog.age = "18"; System.out.println(dog.name+":"+dog.age); } }
运行结果
可以看到我们使用extends关键字便实现了继承!
父类Anmial的属性,子类dog便有了该属性!
看完这个代码,我们好像对继承有了一定理解~
继承语法
class 子类名 extends 父类名 { }
我们知道extends英文意为:扩展,延伸,继承。
那继承有什么用呢?
我们先看下面代码:
class Birdie{ public String name; public int age; public void eat(){ System.out.println(name+"eat()!"); } public void fly(){ System.out.println(name+"fly()!"); } } class Dog{ public String name; public int age; public void eat(){ System.out.println(name+"eat()!"); } public void run(){ System.out.println(name+"run()!"); } } class Frog{ public String name; public int age; public void eat(){ System.out.println(name+"eat()!"); } public void jump(){ System.out.println(name+"jump()!"); } }
我们可以看到Birdie,Dog,Frog类都有一些相同的属性和方法!如果我们利用extends继承,就可以使代码更简洁!
我们可以将所有的类相同的属性抽离出来成一个Anmial父类~所有的类都是Anmial的子类,(is a)的关系, 例如 Birdie is a Anmial 我们就可以采用关键字extends继承关键字!
class Animal{ public String name; public int age; public void eat(){ System.out.println(name+"eat()!"); } } class Birdie extends Animal{ public void fly(){ System.out.println(name+"fly()!"); } } class Dog extends Animal{ public void run(){ System.out.println(name+"run()!"); } } class Frog extends Animal{ public void jump(){ System.out.println(name+"jump()!"); } }
这就是继承简单的作用!继承实现了代码重写的效果!
基础知识
我们所继承的父类,在java中又被称为超类,基类,父类;
而子类又称为派生类,子类
子类要使用extends关键字指定父类;
子类中通过super指代父类对象的引用;
子类可以继承父类的所有public方法和属性;
子类无法继承父类中的private方法和字段;
java只能单继承,只能继承一个父类,无法实现多继承;
子类可以继承父类final和static修饰的属性和方法;
父类中的private修饰的私有属性和方法无法被继承
class Anmail{ public String name; public int age; private String sex = "男"; private int height; public void eat(){ System.out.println(name+":eat()!"); } } class Bired extends Anmail{ } public class Test { public static void main(String[] args) { Bired bired = new Bired(); bired.sex;//无法继承父类中的私有属性和方法 } }
final修饰的属性无法被更改,可以被子类继承!!
class Anmail{ public String name; public int age; public final String sex = "男"; public static int height; public void eat(){ System.out.println(name+":eat()!"); } } class Bired extends Anmail{ } public class Test { public static void main(String[] args) { Anmail anmail = new Anmail(); anmail.sex = "女"; //error 无法改变final修饰的属性和方法 Bired bired = new Bired(); bired.sex = "女";//error 子类也无法改变父类中的final属性和方法 System.out.println(bired.sex); //子类可以继承final修饰的属性和方法 } }
构造方法
当我们子类有构造方法时,要先帮助父类进行构造!
基础语法
我们利用sumper关键字帮助父类构造,调用合适的构造方法即可
class 父类{ public 父类(){ // 父类构造方法 } } class 子类 extends 父类{ public 子类(){ sumper(); //帮助父类构造 } }
//父类只有不带参数的构造方法时 class Animal{ protected String name; protected int age; public void eat(){ System.out.println("Animal::eat()"); } public Animal(){ } } class Bird extends Animal { }
我们知道编译器会自动帮助我们编写不带参数的构造方法!
所以其实子类中也有构造方法
//当父类中有含有参数的构造方法时 class Animal{ protected String name; protected int age; public void eat(){ System.out.println("Animal::eat()"); } public Animal(String name,int age){ this.name = name; this.age = age; } } class Bird extends Animal { //子类也需要帮助父类构造含参数的构造方法 public Bird(String name, int age){ super(name,age); } }
//当父类有多个构造方法时 class Animal{ protected String name; protected int age; public void eat(){ System.out.println("Animal::eat()"); } public Animal(String name,int age){ this.name = name; this.age = age; } public Animal(){ } } class Bird extends Animal { public Bird(String name, int age){ super(); //调用父类不带参数的构造方法 } }
如果我们不帮父类构造编译器就会报错
_
protected修饰符
通常我们的父类中的字段或者方法会用protected修饰,但也因情况而定
protected修饰的字段和方法权限:相同包的类,不同包中的子类;
也就是说,protected修饰,无法在不同包中的非子类访问。很好的包装了父类!
package demo; public class Animal{ protected String name; protected int age; }
package demo_2; import demo.Animal; public class Bird extends Animal { public void setName(String name){ super.name = name; //继承了demo包下Animal类中的protected方法,字段 } public void setAge(int age){ super.age = age; } }
demo包下的Animal类
demo_2包下的Bird类
组合
我们知道继承是is a的关系,就是什么是什么,bired is anmail
组合就是has a的关系,什么有什么!
我们写代码也会使用到
例如一个学校类,我们需要老师和学生类,
而学校对象就有老师和学生对象!
class Student{ public String name = "bug郭"; public int age = 18; } class Teacher{ public String name ="CSDN"; public int age = 66; } class School{ //组合school has student and teacher. Student student = new Student(); Teacher teacher = new Teacher(); public void show(){ System.out.println(student.name+":"+student.age); System.out.println(teacher.name+":"+teacher.age); } } public class Test_2 { public static void main(String[] args) { School school = new School(); school.show(); } }
this和super关键字
this
父类对象的引用
this() 调用类中的构造方法
只能在构造方法中使用
super
super 表示获取到父类实例的引用. 涉及到两种常见用法。
重载和重写
重载
方法重载就是,在一个类中方法名相同,参数列表不同,返回值无关
class Sum{ public int add(int a,int b){ return a+b; } public int add(int a,int b,int c){ return a+b; } public double add(double a, double b){ return a+b; } }
上面add方法构成方法重载!
重写
啥是重写呢?
重写就是子类中有父类同名的方法就构成了重写
package demo; public class Animal{ protected String name; protected int age; public void eat(){ System.out.println("Animal::eat()"); } } class Bird extends Animal{ //和父类相同的方法 public void eat(){ System.out.println("Bird::eat()"); } }
重写注意事项
方法的返回值和参数列表必须和父类相同才能构成重写
重写的方法返回值类型不一定和父类的方法相同(但是建议最好写成相同, 特殊情况除外)
协变类型
就是子类重写的方法可以返回父类方法返回值的子类!!!
可以看到重写方法的返回值是父子类关系时,也能构成重写!!!
重写和重载的区别
方法重载指的是在一个类中同名的方法
条件:方法名相同,参数列表不同,返回值一般不做要求!
方法重写指的是子类中的方法与父类中的方法同名,且方法的参数列表和返回值都要与父类相同!且子类重写方法的访问修饰限定符的权限要求大于或等于父类中的权限!
条件:继承关系,方法名,参数列表,返回值相同,权限高于或等于父类。
重载对方法的权限不做要求!