零,基本语法
1,基本约定
大小写敏感:Java 是大小写敏感的
类名:类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
主方法入口:所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
2,修饰符
修饰符用来定义类、方法或者变量,通常放在语句的最前端。
访问控制修饰符:
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private : 在同一类内可见,子类不可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public : 对所有类可见。使用对象:类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
非访问修饰符
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
3,数组
数组是储存在堆上的对象,可以保存多个同类型变量。
数组的遍历可以使用for循环,也可以使用for each:
int[] ns = { 1, 4, 9, 16, 25 };
for(int n:ns) {
System.out.println(n);
}
数组的打印如果直接打印的话,会是第一个元素的内存地址,需要使用如下方法:
System.out.println(Arrays.toString(ns));//[1, 4, 9, 16, 25]
数组的排序使用内置的方法,Arrays.sort(arr)
多维数组其实和一层的数组差不多,但是它的直接打印使用的是一个新的方法:Arrays.deepToString(arr)
4,枚举
枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的 bug。
例如,我们为果汁店设计一个程序,它将限制果汁为小杯、中杯、大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。
class FreshJuice {
enum FreshJuiceSize{ SMALL, MEDIUM , LARGE }
FreshJuiceSize size;
}
public class FreshJuiceTest {
public static void main(String[] args){
FreshJuice juice = new FreshJuice();
juice.size = FreshJuice.FreshJuiceSize.MEDIUM ;
}
}
5,关键字
6,注释
public class HelloWorld {
/* 这是第一个Java程序
* 它将输出 Hello World
* 这是一个多行注释的示例
*/
public static void main(String[] args){
// 这是单行注释的示例
/* 这个也是单行注释的示例 */
System.out.println("Hello World");
}
}
7,继承
在 Java 中,一个类可以由其他类派生。如果你要创建一个类,而且已经存在一个类具有你所需要的属性或方法,那么你可以将新创建的类继承该类。
利用继承的方法,可以重用已存在类的方法和属性,而不用重写这些代码。被继承的类称为超类(super class),派生类称为子类(sub class)。
8,接口
在 Java 中,接口可理解为对象间相互通信的协议。接口在继承中扮演着很重要的角色。
接口只定义派生要用到的方法,但是方法的具体实现完全取决于派生类。
9,Java 源程序与编译型运行区别
10,基本数据类型
基本数据类型和js的基本数据类型差不多,定义要更严谨一些。
使用final修饰的变量是常量,不可修改:finl int a=2;
如果懒得写类型定义,可以用var代替,编译器会自动识别出类型:
var sb=new StringBuilder();
等价于:
StringBuilder sb = new StringBuilder();
11,变量
变量从本质上讲,就是内存中的一小块区域,用来暂存数据。
定义变量:数据类型 变量名=变量值
例如int a=19。
1,定义的变量名字不能重复
2,变量未赋值时不能使用
3,long类型的变量定义的时候,为了防止整数过大,后面要加L,如:long a=10000000000L(因为默认是int类型,怕超过int的范围)
4,float类型的变量定义的时候,为了防止类型不兼容,后面要加F,如:float a=3.14F(因为默认是double)
局部变量:方法体中
类变量(静态变量):类中、方法体外,用static修饰
实例变量(成员变量)(非静态变量):类中,方法体外,不用static修饰,属于实例的,得通过实例才能访问。
public class Variable{
static int allClicks=0;
// 类变量,无论一个类创建了多少个对象,类只拥有类变量的一份拷贝
//静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
//大多数静态变量声明为 public 类型
String str="hello world"; // 实例变量,实例变量在对象创建的时候创建,在对象被销毁的时候销毁;访问修饰符可以修饰实例变量;
//实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有(private)。通过使用访问修饰符(public )可以使实例变量对子类可见;
public void method(){
int i =0; // 局部变量,访问修饰符不能用于局部变量,局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
}
}
非静态变量不能在该类的主函数中直接读取,而是需要新建类后才可以。
public class MyTest2 {
String version = "1.5.1";//非静态变量
private void getVersion(){
System.out.println(version);
}
public static void main(String[] args) {
MyTest2 test=new MyTest2();//需要实例化之后才能读取
test.getVersion();
}
}
12,变量的类型转化
自动类型转化:将表示范围小的值或变量转化为表示范围大的变量。
byte,short,char—> int —> long—> float —> double
public class ZiDongLeiZhuan{
public static void main(String[] args){
char c1='a';//定义一个char类型
int i1 = c1;//char自动类型转换为int
System.out.println("char自动类型转换为int后的值等于"+i1);
}
}
强制类型转化:将表示范围大的值或变量转化为表示范围小的变量。
int i1 = 123;
byte b = (byte)i1;//强制类型转换为byte
13,运算符
算术运算符
+,-,*,/,%,++,--
关系运算符
==,!=,>,<,<=,>=
逻辑运算符
&,|,^,!
&&:短路与,和&一样,但是如果左边为真,右边执行,如果左边为假,右边不执行。
||:短路或,和|一样,但是左边为假,右边执行,如果左边为真,右边不执行。
instanceof 运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
一,对象和类
1,类的状态和方法
类:类是一个模板,它描述一类对象的行为和状态
对象:是类的一个实例,她首先具备该类的行为和状态,并且可以有自己的行为和状态。
定义一个类:
public class Dog {
String breed;
int size;
String colour;
int age;
void eat() {
}
void run() {
}
void sleep(){
}
void name(){
}
}
一个java类中,可以有以下几种类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
一个类可以拥有多个方法,在上面的例子中:eat()、run()、sleep() 和 name() 都是 Dog 类的方法。
2,构造方法
每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
public class Puppy{
public Puppy(){
}
public Puppy(String name){
// 这个构造器仅有一个参数:name
}
}
3,创建对象
类名 对象名称 = new 类名();
public class Main {
//Main类的构造方法
public Main(String name){
//这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public static void main(String[] args) {
// 下面的语句将创建一个Main对象
Main myPuppy = new Main( "tommy" );
}
}
4,访问实例变量和方法
和js差不多,Obj.变量名,Obj.方法名()
public class Main{
int puppyAge;//类中的变量
// 这个构造器
public Main(String name){
System.out.println("小狗的名字是 : " + name );
}
//类的方法
public void setAge( int age ){
puppyAge = age;
}
public int getAge( ){
System.out.println("小狗的年龄为 : " + puppyAge );
return puppyAge;
}
//主方法
public static void main(String[] args){
/* 创建对象 */
Main myPuppy = new Main( "tommy" );
myPuppy.setAge( 2 );
myPuppy.getAge( );
System.out.println("变量值 : " + myPuppy.puppyAge );
}
}
5,创建类需要注意的
一个源文件中只能有一个 public 类
一个源文件可以有多个非 public 类
源文件的名称应该和 public 类的类名保持一致
public class Main{
int puppyAge;
public Main(String name){
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public void setAge( int age ){
puppyAge = age;
}
public int getAge( ){
System.out.println("小狗的年龄为 : " + puppyAge );
return puppyAge;
}
public static void main(String[] args){
/* 创建对象 */
Main myPuppy = new Main( "tommy" );
myPuppy.setAge( 2 );
myPuppy.getAge( );
System.out.println("变量值 : " + myPuppy.puppyAge );
Test test1=new Test();
test1.setAge(6);
test1.outTest();
}
}
class Test{
int a;
void setAge( int age ){
a = age;
}
void outTest(){
System.out.println("测试另一个类: " + a );
}
}
6,java包的引入和使用
包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
引入的话,可以使用下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类,当然,同级目录下的两个类,不需要import,因为我们的类名和文件名相同,idea会帮我们找到。
import java.io.*;
新建一个类Dog.java:
public class Dog {
int age;
public Dog(String name){
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
}
public void setAge(int a){
age=a;
}
public int getAge(){
return age;
}
}
在另一个同目录下的类Mytest2.java中直接使用:
public class MyTest2 {
public static void main(String[] args) {
Dog keJi=new Dog("小白");
keJi.setAge(9);
int dogAge=keJi.getAge();
System.out.println("小狗的年龄是"+dogAge);
}
}
二,语句结构
1,while循环
//只要布尔表达式为 true,循环就会一直执行下去。
while( 布尔表达式 ) {
//循环内容
}
2,do…while 循环
//至少会执行一次,直到条件为false
do {
//代码语句
}while(布尔表达式);
3,for循环
for(初始化; 布尔表达式; 更新) {
//代码语句
}
Java5 引入了一种主要用于数组的增强型 for 循环。
Java 增强 for 循环语法格式如下:
for(声明语句 : 表达式)
{
//代码句子
}
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){
System.out.print( x );
}
4,break 关键字
break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。
break 跳出最里层的循环,并且继续执行该循环下面的语句。
for(int b=0;b<5;b++){
System.out.println(b);
if(b>2){
break;
}
}
5,continue 关键字
continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
for(int b=0;b<5;b++){
if(b==2){
continue;
}
System.out.println(b);
}
6,switch……case
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}
三,内置类
1,Number类
2,Math类
Math有提供一些常用的数学方法:
public class MyTest2 {
public static void main(String[] args) {
double a=1.45;
System.out.println(Math.floor(a));//1.0
}
}
Math.parseInt():将字符串解析为int类型。
Math.abs():返回参数的绝对值。
Math.ceil():返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型
Math.floor():返回小于等于(<=)给定参数的最大整数 。
Math.round():它表示四舍五入,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,
3,枚举类
Java 枚举是一个特殊的类,一般表示一组常量。
public class MyTest2 {
public static void main(String[] args) {
System.out.println(Color.RED);
//或者
Color test=Color.RED;
System.out.println(test);
}
}
enum Color
{
RED, GREEN, BLUE;
}
enum 定义的枚举类默认继承了 java.lang.Enum 类。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
values() 返回枚举类中所有的值。
ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
valueOf()方法返回指定字符串值的枚举常量。
public class MyTest2 {
public static void main(String[] args) {
Color test=Color.RED;
System.out.println(test.ordinal());//返回它在Color中对应的索引
System.out.println(Color.valueOf("RED"));//返回它在Color中对应的值
}
}
enum Color
{
RED, GREEN, BLUE;
}
for循环遍历枚举
public class MyTest2 {
public static void main(String[] args) {
Color [] arr= Color.values();//取得Color的值形成数组
for (Color test :arr){
System.out.println(test);
}
}
}
enum Color
{
RED, GREEN, BLUE;
}
四,数组
1,创建数组
dataType[] arrayRefVar = new dataType[arraySize];//int [] test=new int[]{3, 1, 2, 6, 4, 2}
dataType[] arrayRefVar = {value0, value1, ..., valuek};//double[] myList = {1.9, 2.9, 3.4, 3.5};
2,遍历数组
// 打印所有数组元素
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i] + " ");
}
//或者
// 打印所有数组元素
for (double element: myList) {
System.out.println(element);
}
3,数组作为函数的参数
public class MyTest2 {
static void printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
public static void main(String[] args) {
int[] myList = {1, 2, 3, 3};
printArray(myList);
}
}
4,数组作为函数的返回值
之前我们没有返回值时,用的是void,现在有返回值了,则应该是返回值的类型定义:
public class MyTest2 {
static int[] printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
return new int[]{3, 1, 2, 6, 4, 2};
}
public static void main(String[] args) {
int[] myList = {1, 2, 3, 3};
printArray(myList);
}
}
5,Arrays类
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
给数组赋值:通过 fill 方法。
对数组排序:通过 sort 方法,按升序。
比较数组:通过 equals 方法比较数组中元素值是否相等。
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
五,java日期时间
java.util 包提供了 Date 类来封装当前的日期和时间。
Date( )//返回当前时间
Date(long millisec)//返回从 1970 年 1 月 1 日起的时间。参数是毫秒数
六,面向对象
1,类的继承格式
class 父类 {
}
class 子类 extends 父类 {
}
实例:
public class MyTest2 {
public static void main(String[] args) {
Penguin test=new Penguin("小企鹅",5);
test.getName();//小企鹅
}
}
class Animal {
public String name;
private int id;
//构造函数初始化
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是"+ id + "号" + name + ".");
}
}
class Penguin extends Animal{
public Penguin(String myName,int myid){
super(myName, myid);//调用超类的构造方法
}
public void getName(){
System.out.println(name);
}
}
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。即同名覆盖。
子类可以用自己的方式实现父类的方法。
Java 的继承是单继承,但是可以多重继承,
2,super关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
public class MyTest2 {
public static void main(String[] args) {
Penguin test=new Penguin("小企鹅",5);
test.childEat();
}
}
class Animal {
private String name;
private int id;
//构造函数初始化
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
}
class Penguin extends Animal{
public Penguin(String myName,int myid){
super(myName, myid);//调用超类的构造方法
}
void childEat(){
super.eat();//调用超类的方法
}
}
3,this关键字
this关键字:指向自己的引用。
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
}
}
4,final修饰符
使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:
声明类:
final class 类名 {//类体}
声明方法:
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
5,构造器
子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。
如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
public class MyTest2 {
public static void main(String[] args) {
Penguin test=new Penguin("小企鹅",5);
test.childEat();
}
}
class Animal {
private String name;
private int id;
//构造函数初始化
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
}
class Penguin extends Animal{
public Penguin(String myName,int myid){
super(myName, myid);//调用超类的构造方法
}
void childEat(){
super.eat();//调用超类的方法
}
}
6,重写
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
public class MyTest2 {
public static void main(String[] args) {
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法:动物可以移动
b.move();//执行 Dog 类的方法:狗可以跑和走
}
}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
如果子类的方法中,要调用父类的方法,还是使用super来访问。
7,重载
和子类重写父类的方法不同的是,重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
它的作用是可以定义多个同名的方法,只是参数不同罢了。
public class MyTest2 {
public static void main(String[] args) {
Animal a = new Animal(); // Animal 对象
a.move();// 动物可以移动
a.move("小白");//小白可以移动
}
}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
public void move(String name){
System.out.println(name+"可以移动");
}
}
8,多态
允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
而重写,是实现多态的一种重要方式。
实现多态的三个必要条件:
继承
重写
父类对子类引用:该引用才既能可以调用父类的方法,又能调用子类的方法
实例:
public class MyTest2 {
public static void main(String[] args) {
Animal bird1 = new Bird();//这里向上转型为Animal,并且指向子类的引用
bird1.eat();//小鸟吃的是虫子
Animal monkey1 = new Monkey();//这里向上转型为Animal,并且指向子类的引用
monkey1.eat();//猴子吃的是香蕉
doSleep(new Monkey());//这里也是向上转型
}
public static void doSleep(Animal animal) {
// 此时的参数是父类对象,但是实际调用时传递的是子类对象,就是向上转型。
animal.sleep();
}
}
class Monkey extends Animal {
void eat() {
System.out.println("猴子吃的是香蕉");
}
public void sleep() {
System.out.println("猴子正在睡觉");
}
}
class Bird extends Animal {
void eat() {
System.out.println("小鸟吃的是虫子");
}
void fly(){
System.out.println("小鸟会飞");
}
public void sleep() {
System.out.println("小鸟正在睡觉");
}
}
abstract class Animal {
void eat() {
System.out.println("动物吃东西的方法");
}
public void sleep() {
System.out.println("小动物在睡觉");
}
}
值得注意的是Animal bird1 = new Bird();它不是在创建新的Bird实例对象,而是向上转型,这样父类实例bird1就有了指向子类Bird的引用,这样一来,就可以调用子类中被重写的方法。但是向上转型并不能调用子类特有属性和方法,例如上面代码中如果执行bird1.fly();将报错找不到方法。
看看啥是向下转型。
public class MyTest2 {
public static void main(String[] args) {
Animal bird1 = new Bird();//这里向上转型为Animal,并且指向子类的引用
bird1.eat();//小鸟吃的是虫子,eat是重写的方法
//bird1.fly();//fly方法是Bird类特有的方法,向上转型成Animal后不能调用,需要再向下转型,才能访问Bird类的特有属性方法
Bird bird2=(Bird) bird1;//向下转型。范围变小,需要强制转化
bird2.fly();//这时bird2已经是Bird类型,所以可以访问Bird中的特有属性和方法
}
}
class Monkey extends Animal {
void eat() {
System.out.println("猴子吃的是香蕉");
}
}
class Bird extends Animal {
void eat() {
System.out.println("小鸟吃的是虫子");
}
void fly(){
System.out.println("小鸟会飞");
}
}
abstract class Animal {
void eat() {
System.out.println("动物吃东西的方法");
}
}
因为之前是向上转型,所以不能访问子类中的特有属性方法。要想访问子类特有的属性和方法,需要再向下转型一次。又因为向下转型是缩小范围,所以需要强制类型转化。
于是多态可总结如下:
1,访问子类重写方法,需要向上转型。
2,访问子类独有方法,需要先向上转型,而后向下转型
因为我觉得Bird bird1=new Bird()这样新建对象后也能调用子类Bird的eat方法,为什么要使用多态,先创建父类实例,再指向子类,然后调用子类的重写方法呢?直接创建子类的实例,然后调用子类的方法不是也很方便嘛?
然后要访问子类的特有方法,使用多态更麻烦,需要先向上转型,然后再向下转型。
完全没有直接实例化子类来得方便呀?
这个不理解,等我理解了再来改。
9,抽象类
抽象类就是足够抽象的类,他不能直接被实例化,而只能被继承使用。一个类只能继承一个抽象类,而一个类却可以实现多个接口。
public class MyTest2 {
public static void main(String[] args) {
Bird bird1 = new Bird();
bird1.fly();
}
}
class Bird extends Animal {
void eat() {
System.out.println("小鸟吃的是虫子");
}
void fly(){
System.out.println("小鸟会飞");
}
}
abstract class Animal {
void eat() {
System.out.println("动物吃东西的方法");
}
}
而当抽象类有抽象方法时,需要子类继承时,重写抽象方法。
public class MyTest2 {
public static void main(String[] args) {
Bird bird1 = new Bird();
bird1.fly();
}
}
class Bird extends Animal {
void eat() {
System.out.println("小鸟吃的是虫子");
}
void fly(){
System.out.println("小鸟会飞");
}
//抽象类被继承后,抽象方法需要被重写
public void computePay(){
System.out.println("抽象方法的实现");
}
}
abstract class Animal {
void eat() {
System.out.println("动物吃东西的方法");
}
//抽象类定义抽象方法
public abstract void computePay();
}
于是抽象类:
1. 抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
10,封装
封装的实现就是:对内聚合保护,对外解耦提供接口
public class MyTest2 {
public static void main(String[] args) {
Person test=new Person();
test.setName("小明");
System.out.println("名字是"+test.getName());
}
}
class Person{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
这里的name就被保护在类中,类外无法直接访问和修改,只能通过该类对外提供的方法才能访问和修改。
11,接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。
接口不是被类继承了,而是要被类实现。
实例:
public class MyTest2 {
public static void main(String[] args) {
MammalInt test=new MammalInt();
test.eat();
}
}
//定义接口
interface Animal {
public void eat();
public void travel();
}
//使用类实现接口
class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
}
接口的继承
// 文件名: Sports.java
public interface Sports
{
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
// 文件名: Football.java
public interface Football extends Sports
{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
实现Football接口的类需要实现五个方法,其中两个来自于Sports接口。
接口的多继承
既然已经有抽象类了,为啥还要有接口呢?因为类只能单继承,而接口可以实现多继承,也就是可以继承多个父接口。
public interface Hockey extends Sports, Event
七,java包
在编写 Java 程序时,随着程序架构越来越大,类的个数也越来越多,这时就会发现管理程序中维护类名称也是一件很麻烦的事,尤其是一些同名问题的发生。有时,开发人员还可能需要将处理同一方面的问题的类放在同一个目录下,以便于管理。由此产生了包的概念。
包的 3 个作用如下:
区分相同名称的类。
能够较好地管理大量的类。
控制访问范围。
1,包的定义
Java 中使用 package 语句定义包,package 语句应该放在源文件的第一行,在每个源文件中只能有一个包定义语句,并且 package 语句适用于所有类型(类、接口、枚举和注释)的文件。
package 包名;
2,包的使用
在src下新建一个package,然后无论是将原有的类拖进去还是新创建一个类,在这个类的最开始,都会定义这个类: