JAVA-为了代码审计-基础学习DAY3


构造

创建实例的时候,我们经常需要同时初始化这个实例的字段,例如:

Person ming = new Person();
ming.setName("小明");
ming.setAge(12);

初始化对象实例需要3行代码,而且,如果忘了调用setName()或者setAge(),这个实例内部的状态就是不正确的。

能否在创建对象实例时就把内部字段全部初始化为合适的值?

完全可以。

这时,我们就需要构造方法。

创建实例的时候,实际上是通过构造方法来初始化实例的。我们先来定义一个构造方法,能在创建Person实例的时候,一次性传入nameage,完成初始化:

public class Main {
    public static void main(String[] args) {
        Person p = new Person("Xiao Ming", 15);
        System.out.println(p.getName());
        System.out.println(p.getAge());
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String getName() {
        return this.name;
    }

    public int getAge() {
        return this.age;
    }
}

为什么我们之前没有构造         person的类编写构造方法代码却能运行

因为java内部代码自动帮我们构造了

其他构造方法和C++ 差不多相当于初始化 你 person(string n , int name){

this.n = n;

this.name=name;

}

或者  person   (string n){

this.n = n;

this.name=12;

}

方法重载

class Hello {
    public void hello() {
        System.out.println("Hello, world!");
    }

    public void hello(String name) {
        System.out.println("Hello, " + name + "!");
    }

    public void hello(String name, int age) {
        if (age < 18) {
            System.out.println("Hi, " + name + "!");
        } else {
            System.out.println("Hello, " + name + "!");
        }
    }

 重载将hello 这个函数能填写3种情况、

1 括号里什么都没有

2 只有人名

3 人名加年龄

inde0f函数

  • int indexOf(int ch):根据字符的Unicode码查找;

  • int indexOf(String str):根据字符串查找;

  • int indexOf(int ch, int fromIndex):根据字符查找,但指定起始位置;

  • int indexOf(String str, int fromIndex)根据字符串查找,但指定起始位置。

继承JAVA 不像c++是 冒号 java 是extends

protected

继承有个特点,就是子类无法访问父类的private字段或者private方法。例如,Student类就无法访问Person类的nameage字段:

class Person {
    private String name;
    private int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // 编译错误:无法访问name字段
    }
}

 

这使得继承的作用被削弱了。为了让子类可以访问父类的字段,我们需要把private改为protected。用protected修饰的字段可以被子类访问:

class Person {
    protected String name;
    protected int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // OK!
    }
}

因此,protected关键字可以把字段和方法的访问权限控制在继承树内部,一个protected字段和方法可以被其子类,以及子类的子类所访问,后面我们还会详细讲解。

super

super关键字表示父类(超类)。子类引用父类的字段时,可以用super.fieldName。例如:

class Student extends Person {
    public String hello() {
        return "Hello, " + super.name;
    }
}

 

实际上,这里使用super.name,或者this.name,或者name,效果都是一样的。编译器会自动定位到父类的name字段。

但是,在某些时候,就必须使用super。我们来看一个例子:

// super

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming", 12, 89);
    }
}

class Person {
    protected String name;
    protected int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Student extends Person {
    protected int score;

    public Student(String name, int age, int score) {
        this.score = score;
    }
}

运行上面的代码,会得到一个编译错误,大意是在Student的构造方法中,无法调用Person的构造方法。

这是因为在Java中,任何class的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句super();,所以,Student类的构造方法实际上是这样:

class Student extends Person {
    protected int score;

    public Student(String name, int age, int score) {
        super(); // 自动调用父类的构造方法
        this.score = score;
    }
}

但是,Person类并没有无参数的构造方法,因此,编译失败。

解决方法是调用Person类存在的某个构造方法。例如:

class Student extends Person {
    protected int score;

    public Student(String name, int age, int score) {
        super(name, age); // 调用父类的构造方法Person(String, int)
        this.score = score;
    }
}

 总的来说就是继承父类的需要输入的参数时我们子类需要跟一个

super(name, age);

限制能被继承的子类名称

正常情况下,只要某个class没有final修饰符,那么任何类都可以从该class继承。

从Java 15开始,允许使用sealed修饰class,并通过permits明确写出能够从该class继承的子类名称。

例如,定义一个Shape类:

public sealed class Shape permits Rect, Circle, Triangle {
    ...
}

下面这个没看懂  

上述Shape类就是一个sealed类,它只允许指定的3个类继承它。如果写:

public final class Rect extends Shape {...}

是没问题的,因为Rect出现在Shapepermits列表中。但是,如果定义一个Ellipse就会报错:

public final class Ellipse extends Shape {...}
// Compile error: class is not allowed to extend sealed class: Shape

原因是Ellipse并未出现在Shapepermits列表中。这种sealed类主要用于一些框架,防止继承被滥用。

sealed类在Java 15中目前是预览状态,要启用它,必须使用参数--enable-preview--source 15

哦懂了限制的是子类名称而不是参数名称

向上转型

Student s = new Student();
Person p = new Person();
Person p = new Student(); // ???

 第3个对的

 

向下转型

Person p1 = new Student(); // upcasting, ok
Person p2 = new Person();
Student s1 = (Student) p1; // ok
Student s2 = (Student) p2; // runtime error! ClassCastException!

如果测试上面的代码,可以发现:

Person类型p1实际指向Student实例,Person类型变量p2实际指向Person实例。在向下转型的时候,把p1转型为Student会成功,因为p1确实指向Student实例,把p2转型为Student会失败,因为p2的实际类型是Person,不能把父类变为子类,因为子类功能比父类多,多的功能无法凭空变出来。

因此,向下转型很可能会失败。失败的时候,Java虚拟机会报ClassCastException

为了避免向下转型出错,Java提供了instanceof操作符,可以先判断一个实例究竟是不是某种类型:

 

Person p = new Person();
System.out.println(p instanceof Person); // true
System.out.println(p instanceof Student); // false

Student s = new Student();
System.out.println(s instanceof Person); // true
System.out.println(s instanceof Student); // true

Student n = null;
System.out.println(n instanceof Student); // false

算了我打算速看 后面敲代码的题来巩固不然这样学习太慢了

 

<think>好的,用户想从Java基础转向Web3,并希望在一个月内制定一个学习计划,最终完成实战项目。首先,我需要考虑用户已有的Java知识如何迁移到Web3开发中。Web3主要涉及区块链、智能合约和去中心化应用(DApps),而Java在Web3中可能不是主流,但用户可能有后端开发的经验,这对理解某些概念有帮助。 接下来,用户的时间是一个月,需要合理分配时间,确保覆盖基础知识同时有足够时间做项目。通常,Web3学习会涉及Solidity、智能合约开发、工具链如Truffle或Hardhat,以及前端集成。可能需要分阶段安排,每周设定明确目标。 第一阶段可能需要学习区块链基础,比如比特币、以太坊的工作原理,智能合约的概念。然后进入Solidity语言的学习,因为这是以太坊的主要开发语言。用户有Java基础,Solidity的语法虽然不同,但编程逻辑有相通之处,可以强调两者之间的异同,帮助用户更快上手。 第二阶段可以学习开发工具和环境,比如配置Node.js、Hardhat或Truffle框架,以及如何测试和部署合约。这里需要实践,编写简单的智能合约并部署到测试网络。 第三阶段是前端集成,可能涉及JavaScript或React,与智能合约交互。用户有Java经验,可能需要快速学习前端基础,但重点可能放在与区块链的交互部分,如使用Web3.js或Ether.js库。 最后是实战项目,例如开发一个去中心化投票系统或NFT市场。需要确保项目涵盖所学内容,并指导用户如何解决常见问题,比如安全漏洞、Gas优化等。 同时,用户可能需要了解一些常见的安全问题,如重入攻击,这在智能合约开发中很重要。此外,社区资源和文档的推荐也很关键,比如官方文档、Stack Exchange、GitHub仓库等,帮助用户自主解决问题。 需要考虑到用户可能的时间投入,每天建议3-4小时,持续一个月。计划要紧凑但可行,避免过于紧张导致无法完成。另外,项目部署到测试网和主网的步骤可能涉及钱包配置、Gas费用,需要详细说明,但实战项目可能先用测试网避免真实资金消耗。 最后,总结学习路径时,要强调实践的重要性,鼓励用户多动手,参与社区,持续学习,因为Web3技术发展迅速,保持更新很重要。</think>以下是一个针对有Java基础学习者、从零入门Web3开发并完成实战项目的30天学习计划。这个计划结合了区块链基础知识、智能合约开发和DApp实战,帮助你高效过渡到Web3领域。 --- ### **第一阶段:基础认知(Day 1-5)** **目标**:理解区块链核心概念,熟悉以太坊生态 1. **区块链基础**(2天) - 学习比特币原理(UTXO、共识机制、挖矿) - 以太坊核心概念:EVM、Gas、账户模型、智能合约 - 工具初探:MetaMask钱包安装与使用 2. **Web3技术栈**(2天) - 区分Web3与Web2的技术差异 - 了解DApp架构(前端+智能合约+区块链) - 熟悉开发工具链:Remix IDE、Hardhat/Truffle 3. **Solidity语法入门**(1天) - 对比Java学习Solidity语法(变量类型、函数、继承) - 重点掌握:`address`、`payable`、事件(Event)和修饰器(Modifier) --- ### **第二阶段:智能合约开发(Day 6-15)** **目标**:掌握Solidity核心技能并完成简单合约 1. **Solidity进阶**(4天) - 安全编程:重入攻击、溢出防护(使用OpenZeppelin库) - ERC标准:实现ERC-20代币合约(对比Java接口设计) - 合约部署:使用Hardhat部署到测试网(Goerli/Sepolia) 2. **实战项目1:去中心化投票系统**(5天) - 功能设计:创建投票、投票计数、权限控制 - 代码实现: ```solidity contract Voting { struct Proposal { uint id; string name; uint voteCount; } mapping(uint => Proposal) public proposals; function createProposal(string memory _name) public { ... } function vote(uint _proposalId) public { ... } } ``` - 测试与部署:编写Hardhat测试脚本,部署至测试网 --- ### **第三阶段:全栈DApp开发(Day 16-25)** **目标**:从前端到合约的全链路开发 1. **前端集成**(3天) - 快速上手React基础Java开发者注意JSX语法差异) - 连接钱包:使用`ethers.js`或`web3.js`库 - 调用合约:读取链上数据、发送交易(对比Java REST API调用) 2. **实战项目2:NFT市场**(7天) - 合约开发: - 实现ERC-721标准(继承OpenZeppelin模板) - 添加拍卖逻辑:出价、截止时间、撤回资金 - 前端开发: - 展示NFT列表(从合约读取数据) - 实现钱包连接和交易签名 - 集成IPFS:使用Pinata存储NFT元数据 --- ### **第四阶段:进阶与优化(Day 26-30)** **目标**:深入优化和安全加固 1. **合约优化**(2天) - Gas成本优化技巧(减少存储操作、使用`view`函数) - 使用Chainlink预言机获取外部数据 2. **安全审计**(2天) - 使用Slither或MythX进行静态分析 - 常见漏洞防御:闪电贷攻击、权限误配 3. **部署主网 & 项目总结**(1天) - 通过Alchemy/Infura部署至以太坊主网 - 总结项目代码,撰写开发文档 --- ### **学习资源推荐** 1. **文档类** - Solidity官方文档([soliditylang.org](https://soliditylang.org/)) - Ethers.js指南([docs.ethers.org](https://docs.ethers.org/)) 2. **实践平台** - Chainlink学习课程([chain.link/education](https://chain.link/education)) - CryptoZombies互动教程([cryptozombies.io](https://cryptozombies.io/)) 3. **社区** - Stack Exchange Ethereum板块 - 中文社区:登链社区、ETHPlanet --- ### **关键学习建议** 1. **从Java迁移的技巧** -Java的OOP思维应用于Solidity合约设计 - 用JUnit测试经验迁移到Hardhat测试脚本编写 2. **每日实践** - 每天至少写1个智能合约函数并测试 - 参与GitHub开源项目(如Compound、Uniswap)代码阅读 3. **避坑指南** - 避免在合约中使用循环(高Gas消耗) - 始终优先使用审计过的库(如OpenZeppelin) 通过这个计划,你将在30天后具备独立开发简单DApp的能力,并拥有2个可展示的实战项目(GitHub代码+部署地址)。Web3技术迭代迅速,建议后续持续关注Layer2(Optimism、Arbitrum)和零知识证明(ZK-SNARKs)等前沿方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值