数据类型
基本数据类型
数据类型 | 默认值 | 大小 |
---|---|---|
boolean | false | 1bit |
char | '\u0000' | 2Byte |
byte | 0 | 1Byte |
short | 0 | 2Byte |
int | 0 | 4Byte |
long | 0L | 8Byte |
float | 0.0f | 4Byte |
double | 0.0 | 8Byte |
引用数据类型
对象、数组
数组声明:
type[] arr = new type[length];
type:任意数据类型
区别:
1.默认值不同 内置数据类型不手动初始化会有不同的默认值
引用数据类型默认值为null
2.参数传递方式不同 值传递和引用传递
注意:
两个Integer对象比较的问题
当Integer值在-128~127之间时,会进行缓存,不会new新的对象
Integet a = 127;
Integet b = 127;
System.out.println(i == j);//true
Integet a = 128;
Integet b = 128;
System.out.println(i == j);//false
//直接new
Integer i = new Integer(100);
Integer j = new Integer(100);
System.out.println(i == j);//false
修饰符
修饰符类型 | 类内部 | 本包 | 字类 | 外部包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | X |
private | √ | X | X | X |
default | √ | √ | X | X |
面向对象
面向对象三大特征:封装、继承、多态 作用:提高安全性+实现代码的组件化
private修饰的方法,成员变量,构造器只能在本类被直接访问
规范:成员变量私有+提供成套的gettersetter方法暴露成员变变量的取值和赋值
public修饰符是公开的意义
注意:合理隐藏+合理暴露
类:描述相同事物的共同特征的抽象
对象:是具体存在的实例(实例 == 对象)
定义类的格式:
修饰符 class 类名
{
//1.成员变量(Field,描述类和对象的属性信息)
//2.成员方法(Method,描述类或者对象的行为信息)
//3.构造器(Constructor,初始化一个类的对象并返回引用)
//4.代码块
//5.内部类
}
注意:
类名的首字母大写,驼峰式命名
一个Java代码文件中可以定义多个类,但是只能有一个类是由public修饰的,而且public修饰的类名必须成为代码的文件名称
类有且只有五大成分
如这行报错代码
public class ClassDemo1{
System.out.println("Hello");
}
构造器
作用:初始化一个类的对象并返回引用,初始化对象的数据
格式:
修饰符 类名(形参){
//...
}
构造器初始化对象格式:
类名 对象名称 = new 构造器;
注意:一个类默认会自带一个无参数构造器,若已经写了一个构造器,无参构造器被覆盖
public class Person{
public String name;
public int age;
public Person(){
System.out.println("无参构造器调用");
}
public Person(String name , int age){
this.name = name;
this.age = age;
System.out.println("有参构造器调用");
}
}
public class Test{
public static void main(String[] args){
Person p1 = new Person();
s1.name = "小可爱";
s1.age = 10;
}
}
this关键字
表示所在类的当前对象的引用(地址值), 即代表当前对象
应用:getter/setter方法 构造器(上面有)
public String getName(){
return name;
}
public String setName(String name){
this.name = name;
}
static关键字
Java通过成员变量是否有static关键字来区分属性是属于类还是对象的
static == 静态 == 修饰的成员(方法和成员变量)属于类本身
成员变量的分类与访问
按照有无static修饰静态成员变量分为:
静态成员变量(类变量):
有static修饰的成员变量称为静态成员变量(类变量),属于类本身,直接用类名访问即可,与类一起加载一次
修饰符 static 数据类型 变量名 = 初始值;
访问静态成员变量
类名.静态成员变量
栗子:
public class Person{
public static String name = "小可爱";
}
//访问
System.out.println(Person.name);//小可爱
Person.name = "大可爱";//用类名直接访问
System.out.println(Person.name);//大可爱 --只有一份
实例成员变量:
无static修饰,属于类的每个对象,必须用类的对象来访问,对象有多少个,就加载多少份
访问实例成员变量
对象.实例成员变量
public class Person{
public int age = 10;
}
//访问
Person p = new Person();
System.out.println(Person.age);//10
Person.age = 20;
System.out.println(Person.age);//20
成员方法
静态方法
有static修饰的成员方法称为静态方法(类方法),属于类本身,直接用类名访问即可
类名.静态方法
对象.静态方法
实例方法
无static修饰的成员方法,属于类的每个对象,必须用类的对象访问(和上面类似了)
几个小问题
实例方法是否可以直接访问实例成员变量?可以,因为它们都属于对象
实例方法是否可以直接访问静态成员变量?可以,静态成员变量可以被共享访问
实例方法是否可以直接访问实例方法?可以,实例方法都属于对象
实例方法是否可以直接访问静态方法?可以,静态方法可以被共享访问
public class Test {
//静态成员变量
public static String name = "小可爱";
//实例成员变量
private int age;
public void run(){
System.out.println(name);//相当于this.name,还是通过对象来访问了
//访问静态成员变量
System.out.println(age);//访问实例成员变量
run1();//相当于this.run1();
run2();//相当于Test.run2();
}
public void run1(){
}
public static void run2(){
}
}
静态方法是否可以直接访问实例成员变量?不可以,实例变量必须用对象访问
静态方法是否可以直接访问静态成员变量?可以,静态成员可以被共享访问
静态方法是否可以直接访问实例方法?不可以,实例方法必须用对象访问
静态方法是否可以直接访问静态方法?可以,静态成员可以被共享访问
public static void run(){
System.out.println(name);//访问静态成员变量
//System.out.println(age);//静态方法不可以访问实例成员变量
//run1();//静态方法不可以访问实例方法
run2();//静态方法访问静态方法}
}
继承
当许多类中存在相同的属性和行为时,可以将这些相同的部分抽象成一个单独的类作为父类,子类直接继承父类即可以获得类中的信息,从而提高代码的复用性
语法
class 子类 extends 父类{}
注意:Java是单继承,一个类只能有一个直接父类
子类不能继承的部分
构造器!
注意:子类是可以继承父类的私有成员,但是无法直接访问,可以通过getter/setter方法访问父类的私有成员变量
继承后的特点
成员变量不重名的情况下,访问时不会出现冲突的
class Base{
int num1 = 1;
}
class Son extends Base{
int num2 = 2;
public void showInfo(){
System.out.println("num1=" + num1);//直接访问从父类继承来的变量
System.out.println("num2=" + num2);//直接访问子类中的成员变量
}
}
若出现重名了,子类会优先访问自己对象中的成员变量
super关键字
super代表父类对象的引用(this代表当前对象的引用)
在子类中访问父类中非私有成员变量时,需要使用super关键字
解决上面的重名问题:
class Base{
int num = 1;
}
class Son extends Base{
int num = 2;
public void showInfo(){
System.out.println("num1=" +super.num1);//直接访问从父类继承来的变量
System.out.println("num2=" + this.num2);//直接访问子类中的成员变量
}
}
方法重写
原则:一同两小一大
一同:
实例方法签名相同(方法签名=方法名+方法的参数列表)
两小:
1.子类方法的返回值类型小于等于父类方法的返回值类型
2.子类方法声明抛出的异常类型小于等于父类方法声明抛出异常类型
一大:
子类方法的访问权限大于等于父类方法的访问权限
注:private修饰的方法不能重写
即:
当子类出现与父类一模一样的方法时(返回值类型、方法名和参数列表都相同),会覆盖。(声明不变,重新实现)
使用重写注解
@Override
public class Animal{
public void run(){
System.out.println("Animal跑");
}
}
public class Cat{
public void run(){
System.out.println("Cat跑");
}
}
继承后的构造器
继承后子类构造器的特点:子类的所有构造器的第一行都会先调用父类的无参构造器,再执行自己的构造器
因为子类继承父类时继承到了父类的数据,需要通过调用父类构造器进行初始化
public class TestDemo1 {
public static void main(String[] args) {
Son s = new Son(10); //Base无参构造器 Son的有参构造器
}
}
class Son extends Base{
private int num;
public Son(){
//super();//假装这里有一行
System.out.println("Son的无参构造器");
}
public Son(int num){
System.out.println("Son的有参构造器");
}
}
class Base{
private int age;
public Base(){
System.out.println("Base无参构造器");
}
public Base(int age){
System.out.println("Base有参构造器");
}
}
可以通过super关键字调用父类构造器
super(...)可以根据参数调用父类的某个构造器
public class TestDemo2 {
public static void main(String[] args) {
Student stu = new Student();//父类无参构造器
//方式1 getter / setter
stu.setAge(20);
//方式2 通过参数列表+super调用父类有参构造器
Student stu2 = new Student("小蔡", 30);
//Alt+Enter获取自动提示+创建构造器
stu2.run();
}
}
class Student extends Person{
public Student(){
System.out.println("子类无参构造器");
}
public Student(String name, int age) {
//自动生成了一个空的构造器,要手动super一把
super(name, age);//系统自动调用了匹配的父类构造器
//创建了这样一个构造器,无参构造器就不自动给了,这个还是要注意
}
public void run(){
System.out.println(getAge() + "的" + getName() +
"正在跑步");
}
}
super和this总结again
this代表当前对象的引用
- this.子类成员变量
- this.子类成员方法
- this(...)可以根据参数匹配访问本类其他构造器
super代表了父类对象的引用(继承中指代了父类对象空间)
- super.父类成员变量
- super.父类的成员方法
- super(...)可以根据参数匹配访问父类的构造器
注意:this(...)和super(...)必须放在构造器的第一行,否则会报错,所以super(...)和this(...)不能同时出现在构造器
通过this调用本类其他构造器案例
public class broTest{
Student s1 = new Student("小可爱", 10);//想实现schoolName有默认值效果
Student s2 = new Student("大可爱", 10, "vvv");//同样还是可以调用有三个参数的构造器
}
class Student{
private String name;
private int age;
private String schoolName;
Student(String name, int age){
//接用兄弟构造器
this(name, age, "NUAA");
//Ctrl点击一下可以
}
Student(String name, int age, String schoolName){
this.name = name;
this.age = age;
this.schoolName = schoolName;
}
//getter/setter..
}
Java继承的特点
1.单继承:一个类只能继承一个直接父类
why?
反证法,假设Java可以多继承
class A{
public void test(){
System.out.println("A");
}
}
class B{
public void test(){
System.out.println("B");
}
}
class C extends A, b{
public static void main(String[] args){
C c = new C();
c.test();//出现类的二义性
}
}
2.多层继承:一个类可以间接继承多个父类
class A{}
class B extends A{}
class C extends B{}
3.一个类可以有多个子类
4.一个类默认继承了Object类,或是间接继承了Object类
引用类型作为方法参数
对象回调:先传入一个对象,再利用对象去调用类中的方法
public class Test{
public static void main(String[] args) {
Person p = new Person();
go(p);
}
public static void go(Person p){
System.out.println("比赛开始");
p.run(); //返回去调用Person中的方法
System.out.println("比赛结束");
}
}
class Person{
public void run(){
System.out.println("跑!...");
}
}
引用类型作为返回值
public class Test{
public static void main(String[] args) {
Person per = createPerson(); //通过方法创建对象,per存储了Person类型的对象p的地址
}
}
public static Person createPerson(){//返回值是Person类型
Person p = new Person();
//可以在方法里对对象进行加工
return p;//返回Person类型的对象(地址)
//精简写法
//return new Person();
}
引用类型作为成员变量(复合类型)
当存储具有较长内容的信息时,可以使用引用类型进行描述
public class Student{
private String name;
private int age;//地址信息 保存一个地址对象信息
private Address address;
....
public Address getAddress() {
return address;
}
//需要接收一个地址对象
public void setAddress(Address address) {
this.address = address;
}
}
public class Address {
private String code;//邮编
private String name;//地址名
...
}
public class TestDemo {
public static void main(String[] args) {
Student s = new Student();
s.setName("ccc");
s.setAge(19);
//处理对象的标准方式
Address addr = new Address("12312", "秦淮河");
//传入一个地址对象
s.setAddress(addr);
//get到的和set到的是同一个对象
Address addr1 = s.getAddress();
//sout...
}